运算符重载不是语法糖,而是接口契约;operator+ 应返回值而非引用,因结果为新对象,返回引用易致悬垂;operator+= 必为成员函数并返回 *this 引用以支持链式赋值;全局 operator+ 用于左操作数非本类(如 int + MyClass),常复用 operator+= 实现。

运算符重载不是语法糖,是接口契约;operator+ 被调用时,编译器不关心你加的是两个 int 还是两个自定义类,只检查是否提供了匹配的重载函数——没提供就报错,提供了但签名不对也报错。
为什么 operator+ 通常返回值而非引用
加法是纯计算操作,结果是新对象,不是对任一操作数的修改。返回引用会引发悬垂引用风险:比如在函数内构造临时对象并返回其引用,调用方拿到的就是野指针。
常见错误现象:error: cannot bind non-const lvalue reference to an rvalue —— 这往往是因为你把 operator+ 声明成了 MyClass& operator+(...),而右侧表达式产生的是临时对象(rvalue)。
- 正确做法:声明为
MyClass operator+(const MyClass& lhs, const MyClass& rhs) - 若类含大内存(如动态数组),可考虑移动语义:返回
MyClass&&并在实现中用std::move,但前提是内部资源可转移 - 不要为了“效率”强行返回引用,C++17 的 NRVO 和 RVO 通常能消除返回值拷贝开销
operator+= 必须返回 *this 引用
这是为了支持链式赋值,比如 a += b += c。语言要求 += 是成员函数(不能是全局),且必须返回 MyClass&。
使用场景:当需要原地修改左操作数、避免构造中间对象时,operator+= 比 operator+ 更高效,尤其对字符串、向量等容器类。
- 实现模板:
MyClass& operator+=(const MyClass& other) { /* 修改 this */ return *this; } - 注意:若类管理资源(如指针),
+=中需先释放原有资源再合并,否则内存泄漏 - 别忘了
const正确性:参数用const MyClass&,函数末尾加const仅当不修改成员;但+=一定修改,所以不能加const
全局 operator+ 和成员 operator+ 怎么选
核心原则:当左操作数是当前类类型,且右操作数可隐式转换为该类(或本身就是该类),优先用成员函数;当左操作数是内置类型(如 int + MyClass),必须用全局函数(因为不能给 int 加成员)。
性能影响:成员版天然访问 private 成员,无需 friend;全局版若需访问私有成员,得加 friend 声明,但这会破坏封装边界。
- 推荐组合:
operator+=作为成员函数,operator+作为非成员函数,内部复用+=:return MyClass(lhs) += rhs; - 错误写法:
operator+声明为成员却只接受一个参数(它默认带this,所以形参只能是右操作数),导致无法处理MyClass + int这类混合类型 - 兼容性注意:C++20 起支持三路比较运算符(
),但加减法仍需手动重载,没有自动推导
最易被忽略的点:运算符重载函数的 const 修饰和参数传递方式必须严格匹配调用上下文;一个 const MyClass 对象调用 operator+ 时,若重载函数没声明为 const(对成员函数而言)或参数不是 const&,编译直接失败——这不是警告,是硬性约束。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











