重载运算符是接口设计而非语法糖,需严格遵循语义:对称运算符用非成员函数(常配friend),修改状态的用成员函数,流操作符只能是非成员;返回类型、const正确性及隐式转换控制至关重要。

重载运算符不是语法糖,是接口设计——写错位置、忘掉 const、返回类型不对,编译器不会帮你兜底,只会报一串你看不懂的错误。
成员函数 vs 全局函数:什么时候必须用哪个?
-
operator+、operator==这类对称运算符,推荐用**非成员函数**(常配合friend),否则右操作数无法触发用户定义的隐式转换 -
operator+=、operator++(前置/后置)、operator[]必须是**成员函数**,因为要修改当前对象状态 operator 和operator>>**只能是非成员函数**,因为左操作数是std::ostream/std::istream,你不能给标准库类加成员
返回值类型陷阱:别随便返回 void 或局部对象
运算符语义决定了返回什么:
-
operator+=应返回*this(T&),支持链式调用:a += b += c; -
operator+应返回T(值语义),不是T&——否则可能返回局部对象引用,导致悬垂引用 -
operator[]通常返回T&(非常量版本)和const T&(常量版本),否则无法对元素赋值或在 const 对象上调用 -
operator==必须返回bool,且建议声明为const成员或接受两个const T&
后置递增(operator++(int))怎么写才不翻车?
后置递增必须带 int 形参(仅作标记,不使用),且行为上要「先返回旧值,再自增」:
立即学习“C++免费学习笔记(深入)”;
T T::operator++(int) {
T old = *this; // 拷贝当前状态
++(*this); // 复用前置递增逻辑(推荐)
return old; // 返回旧副本
}
常见错误:
- 忘了形参
int,编译器会当成前置版本,导致重定义错误 - 直接返回
*this而不是拷贝,结果和前置行为一样 - 手动实现自增逻辑,重复代码且易出错——应优先复用
operator++()
隐式转换 + 运算符重载 = 意外调用?
如果你写了 MyString(const char*) 构造函数但没加 explicit,又重载了 operator+,那么 "hello" + mystr 就可能意外触发构造 + 运算符调用,性能差还难调试。
- 所有单参数构造函数,除非真想支持隐式转换,否则一律加
explicit - 如果真需要字符串字面量参与运算,显式写成
MyString("hello") + mystr - 考虑用
std::string_view参数替代const char*,减少临时对象构造
最常被忽略的是 const 正确性:90% 的 operator==、operator[](const 版)、operator* 等只读操作,漏加 const 会导致无法在 const 对象上调用——这不是警告,是硬性编译失败。








