operator+ 可定义为成员函数或友元函数:仅支持MyClass + MyClass时用const成员函数;需支持int + MyClass时必须用友元函数。应返回MyClass值类型,参数用const引用,且优先复用operator+=实现。

operator+ 必须定义为类的友元还是成员函数?
取决于是否需要左操作数是其他类型(比如 int + MyClass)。如果只支持 MyClass + MyClass,成员函数足够;但只要想让 5 + obj 合法,就必须用友元函数——因为成员函数的隐式 this 指针总在左边,无法把 int 当作 this。
常见错误:只写成员版 operator+,然后写 5 + obj 编译失败,报错类似 no match for 'operator+' (operand types are 'int' and 'MyClass')。
- 成员函数版本:自动获得
MyClass类型的左操作数,右操作数由参数传入 - 友元函数版本:两个操作数都显式声明,可自由组合类型
- 若同时支持
MyClass + int和int + MyClass,通常要写两个友元重载
返回值类型为什么不能是 void 或引用?
operator+ 的语义是“产生新对象”,不是修改原对象。返回 void 会导致 a + b + c 无法链式调用;返回非 const 引用(比如 MyClass&)容易引发悬垂引用——因为返回的通常是局部对象。
正确做法是返回 MyClass(值语义),或在 C++11 后可考虑返回 MyClass&& 配合移动构造,但初学者优先用值返回。
立即学习“C++免费学习笔记(深入)”;
- 错误示例:
MyClass& operator+(const MyClass& other) { return *this; }—— 返回自身引用,破坏加法语义 - 安全写法:
MyClass operator+(const MyClass& other) const - 加上
const修饰成员函数,表示不修改当前对象
如何避免重复实现 operator+= 和 operator+?
直接复用 operator+= 是惯用手法:先实现 operator+=(它修改左操作数,适合用成员函数),再让 operator+ 基于它构造新对象。这样逻辑集中、不易出错,也符合“复合赋值操作符是基础”的设计习惯。
注意:operator+= 应返回 MyClass&(支持链式赋值如 a += b += c),而 operator+ 不应调用它来修改任何实参。
class MyClass {
int value_;
public:
MyClass(int v = 0) : value_(v) {}
MyClass& operator+=(const MyClass& other) {
value_ += other.value_;
return *this;
}
friend MyClass operator+(const MyClass& a, const MyClass& b) {
MyClass result = a; // 复制左操作数
result += b; // 复用 += 逻辑
return result;
}
};
operator+ 参数为什么要用 const 引用?
避免不必要的拷贝,同时允许传入临时对象和 const 对象。如果写成 MyClass operator+(MyClass a, MyClass b),会触发两次拷贝构造;而 const MyClass& 既高效又安全。
另一个关键点:如果类管理资源(如动态内存),且没实现移动构造,传值参数还可能意外触发深拷贝,拖慢性能甚至引发异常。
- 禁止写
MyClass operator+(MyClass a, MyClass b) - 推荐写
friend MyClass operator+(const MyClass& a, const MyClass& b) - 如果右操作数是字面量或临时对象(如
obj + MyClass(42)),const &仍能绑定
operator+ 最容易被忽略的是对称性——你得主动决定要不要支持反向操作(比如 int + MyClass),而不是默认就有。一旦漏掉友元声明或参数顺序写反,编译器不会提示“你可能忘了左操作数是 int”,只会报“找不到匹配函数”。











