一元运算符 +、- 和 ! 的重载

一、一元运算符重载概述
与之前介绍的运算符不同,正号(+)、负号(−)与逻辑非(!)均为一元运算符,即仅作用于单个操作数。由于它们只针对被施加的对象进行运算,通常以成员函数的形式实现重载。上述三种运算符的实现方式完全一致。

在 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+ 仅返回操作数本身(不会将负值变为正值)。

关注公众号,回复"cpp-tutorial"

可领取价值199元的C++学习资料

公众号二维码

扫描上方二维码或搜索"cpp-tutorial"