运算符重载是接口设计而非语法糖;必须用成员函数的包括=、[]、()、->及需访问私有成员或修改this的场景;必须用友元的包括左操作数非本类(如int+MyString)或需访问多类私有成员的情形。

运算符重载不是“语法糖”,而是接口设计——写错地方、选错函数类型,编译器会直接报错或行为诡异,比如 operator+ 返回临时对象却用 & 接收,或者把 operator== 写成非 const 成员导致 const 对象无法比较。
什么时候必须用成员函数重载
涉及隐式 this 参数修改、访问私有成员,或重载赋值 =、下标 []、函数调用 ()、箭头 -> 这四类运算符时,只能定义为类的成员函数。
-
operator=必须是成员函数:编译器自动生成的默认赋值操作符也是成员,自定义时若写成友元,连基本赋值都会编译失败 -
operator[]要返回可被取地址的引用(如int&),只有成员函数能天然访问内部数组/容器并返回其元素引用 - 重载
operator++前置版本(++a)推荐用成员函数,避免额外构造临时对象
什么时候必须用友元函数重载
当左操作数不是当前类类型(比如 int + MyString),或需要同时访问两个不同类的私有成员时,必须用友元函数——因为成员函数的左操作数固定是 *this。
operator 和 <code>operator>>几乎总是友元:std::cout 中左操作数是 <code>std::ostream&,不可能是你的类- 对称二元运算符如
+、==、!=,若希望支持obj + 5和5 + obj,5 + obj只能靠友元实现 - 友元声明写在类内(如
friend MyString operator+(const MyString&, const char*);),定义在类外,不破坏封装性
const 和引用返回值怎么配
返回值类型和参数 const 修饰共同决定能否绑定、是否安全。错配会导致编译失败或悬垂引用。
立即学习“C++免费学习笔记(深入)”;
-
operator==参数必须是const &(如const MyString& other),否则无法比较const对象 -
operator+应返回MyString(值语义),不是MyString&:返回局部对象的引用是未定义行为 -
operator[]需要重载两个版本:T& operator[](size_t i)和const T& operator[](size_t i) const,否则const对象调用会失败
容易被忽略的移动语义陷阱
C++11 后,如果类管理动态资源(如指针、文件句柄),重载 operator= 时不处理右值引用,就可能漏掉移动优化,甚至引发重复释放。
- 别只写
MyClass& operator=(const MyClass& other),补上移动赋值:MyClass& operator=(MyClass&& other) noexcept - 移动赋值里记得把
other的资源置空(如将指针设为nullptr),否则析构时二次释放 - 如果用了
std::vector等标准容器,编译器生成的移动操作通常够用;但手写资源管理时,漏掉移动重载会让std::move(obj1) = obj2退化为拷贝
最常出问题的不是语法,而是没想清楚这个运算符在表达什么语义:是创建新值(+)、修改自身(+=)、还是提供访问入口([])。一旦语义模糊,const、引用、返回值类型就全跟着错。


















