重载一元运算符+, - 和!
重载一元运算符
与您目前看到的运算符不同,正(+),负( - )和逻辑非(!)运算符都是一元运算符,这意味着它们只能在一个操作数上运行。因为它们仅对它们所应用的对象进行操作,所以通常将一元运算符重载实现为成员函数。所有三个操作数都以相同的方式实现。
让我们看一下我们如何在前面的例子中使用的Cents类上实现operator-:
#include <iostream>
class Cents
{
private:
int m_cents;
public:
Cents(int cents) { m_cents = cents; }
// 作为一个成员函数实现重载 -Cents
Cents operator-() const;
int getCents() const { return m_cents; }
};
//注意:此函数是成员函数!
Cents Cents::operator-() const
{
return Cents(-m_cents);
}
int main()
{
const Cents nickle(5);
std::cout << "A nickle of debt is worth " << (-nickle).getCents() << " cents\n";
return 0;
}
这应该是直截了当的。我们的重载负运算符( - )是作为成员函数实现的一元运算符,因此它不带参数(它在* this对象上运行)。它返回一个Cents对象,它取决于原始的Cents值。因为operator-不修改Cents对象,所以我们可以(并且应该)使它成为const函数(因此可以在const Cents对象上调用它)。
注意,负操作符和减号操作符之间没有混淆 - 因为它们具有不同数量的参数。
这是另一个例子。的!operator是逻辑否定运算符 - 如果表达式的计算结果为“true”,则运算符!将返回false,反之亦然。我们通常会看到这个应用于布尔变量来测试它们是否为真:
if (!isHappy)
std::cout << "I am not happy!\n";
else
std::cout << "I am so happy!\n";
对于整数,0的计算结果为false,其他任何结果为true,因此运算符!如果应用于整数,则对于整数值0将返回true,否则返回false。
扩展概念,我们可以说是operator!如果对象的状态是“假”,“零”或默认初始化状态,则应评估为true。
以下示例显示了operator- 和 operator!的重载,对于用户定义的Point类:
#include <iostream>
class Point
{
private:
double m_x, m_y, m_z;
public:
Point(double x=0.0, double y=0.0, double z=0.0):
m_x(x), m_y(y), m_z(z)
{
}
// 将Point转换为负等效值
Point operator- () const;
// 如果将点设置在原点,则返回true
bool operator! () const;
double getX() { return m_x; }
double getY() { return m_y; }
double getZ() { return m_z; }
};
// 将Point转换为负等效值
Point Point::operator- () const
{
return Point(-m_x, -m_y, -m_z);
}
// 如果点设置在原点,则返回true,否则返回false
bool Point::operator! () const
{
return (m_x == 0.0 && m_y == 0.0 && m_z == 0.0);
}
int main()
{
Point point; // 使用默认构造函数设置为 (0.0, 0.0, 0.0)
if (!point)
std::cout << "point is set at the origin.\n";
else
std::cout << "point is not set at the origin.\n";
return 0;
}
重载运算符!如果Point设置为坐标(0.0,0.0,0.0)处的默认值,则此类返回布尔值“true”。因此,上面的代码产生了结果:
point is set at the origin.
Quiz Time:
1)为Point类实现重载operator +。
解决方案
这是显而易见的解决方案:
Point Point::operator+ () const
{
return Point(m_x, m_y, m_z);
}
但是因为我们返回的Point与我们正在操作的那个完全相同,所以下面也有效:
Point Point::operator+ () const
{
return *this;
}