一、一元运算符重载概述
与之前介绍的运算符不同,正号(+)、负号(−)与逻辑非(!)均为一元运算符,即仅作用于单个操作数。由于它们只针对被施加的对象进行运算,通常以成员函数的形式实现重载。上述三种运算符的实现方式完全一致。
在 Cents 类中重载 operator-
以下示例展示如何在先前用过的 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 -m_cents; // 返回类型为 Cents,因此编译器会借助 Cents(int) 构造函数将 int 隐式转换为 Cents
}
int main()
{
const Cents nickle{ 5 };
std::cout << "A nickle of debt is worth " << (-nickle).getCents() << " cents\n";
return 0;
}
代码含义清晰:
- operator- 是一元运算符,以成员函数实现,故无显式形参(它通过 *this 操作对象)。
- 该运算符返回一个新的 Cents 对象,其值为原对象的相反数。
- 因 operator- 不修改原对象,且需在 const 对象上调用,故将其声明为 const 成员函数。
- 负号运算符(一元)与减法运算符(二元)因参数个数不同,不会产生歧义。
operator! 的行为与示例
逻辑非运算符 ! 用于逻辑取反:若表达式为“真”,则返回 false;反之返回 true。
对布尔变量常见用法如下:
if (!isHappy)
std::cout << "I am not happy!\n";
else
std::cout << "I am so happy!\n";
对于整型,0 视为 false,其余值视为 true;故对整数使用 operator! 时,0 返回 true,非 0 返回 false。
将此概念扩展到自定义类型:若对象处于“假”“零”或默认初始化状态,operator! 应返回 true。
以下示例同时重载 operator- 与 operator!:
#include <iostream>
class Point
{
private:
double m_x {};
double m_y {};
double 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 operator- () const;
// 若点位于原点则返回 true
bool operator! () const;
double getX() const { return m_x; }
double getY() const { return m_y; }
double getZ() const { return m_z; }
};
// 返回负点坐标
Point Point::operator- () const
{
return { -m_x, -m_y, -m_z };
}
// 若坐标为原点 (0.0, 0.0, 0.0) 则返回 true
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 is set at the origin.
练习
请在 Point 类中实现一元 operator+。一元 operator+ 仅返回操作数本身(不会将负值变为正值)。