之前这篇函数重载:同名函数如何共存?说过函数重载,现在这篇来聊聊操作符重载。

操作符重载语法

在 C++ 中,操作符重载的实质是定义一个函数,但函数名不是普通的标识符,而是 operator 后紧跟要重载的操作符。

核心语法: 返回类型 operator@ (参数列表);

例如:complex& operator+= (const complex& r); 表示重载 += 操作符。

C++ 希望使用自定义类型时能像内置类型一样自然。例如 c2 += c3c2.add(c3) 更直观,因为复数运算本就是数学符号。C++ 允许你将 += 重新定义为成员函数,让语法贴近数学。

不能重载的操作符有:.(成员访问)、::(作用域解析)、.*(成员指针访问)、?:(条件三目)。重载后,操作符的优先级和结合性不会改变。只能重载已有的操作符,不能发明新的(如 ** 在 C++ 中不合法)。

隐藏的 this 指针

编译器在处理成员函数时,会自动为每个非静态成员函数添加一个隐藏参数,即 this 指针。这解释了为什么成员函数内部可以直接访问调用对象的数据。

核心概念:this 指针

  • this 是一个指针,其类型是 ClassName * const(指针本身不能被修改,但指向的对象可改)。
  • 它存储了调用该成员函数对象的地址。
  • 你不需要写 this,也不能在参数列表中显式声明它。但可以在函数体中使用它(例如 this->real 访问成员,或 return *this 返回当前对象)。

编译器视角的变换:源代码:c2 += c3;
编译器转换为:c2.operator+=(c3);
进一步,编译器在内部把 c2 的地址传给隐藏的 this 参数:operator+=(&c2, c3);

很多初学者困惑:为什么成员函数可以“凭空”访问 realimag?这正是 this 的秘密。

当你写 real += r.real; 时,实际上就是 this->real += r.real;

this 自动指向 c2,所以 real 就是 c2.real

二元操作符

对于二元操作符(如 +, +=, *, < 等),当使用成员函数形式重载时,必须遵守左操作数是本类对象的约定。

核心概念:左操作数(左值)与右操作数(右值)

  • 在表达式 a @ b 中,a 是左操作数,b 是右操作数。
  • 如果 @ 被重载为成员函数,则:a @ b 等价于 a.operator@(b)
  • 因此,左操作数 a 必须是类的对象(或对类对象的引用),因为它是成员函数的调用者。

注意:如果左操作数不是本类类型(例如 double + complex),则不能用成员函数重载。此时必须使用非成员函数形式