C++重载运算符怎么写 C++ operator操作符重载实例大全【教学】

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

重载运算符不是语法糖,是接口设计——写错位置、忘掉 const、返回类型不对,编译器不会帮你兜底,只会报一串你看不懂的错误。

成员函数 vs 全局函数:什么时候必须用哪个?

核心区别在左操作数是否可修改、是否需要隐式转换:

  • operator+operator== 这类对称运算符,推荐用**非成员函数**(常配合 friend),否则右操作数无法触发用户定义的隐式转换
  • operator+=operator++(前置/后置)、operator[] 必须是**成员函数**,因为要修改当前对象状态
  • operator 和 operator>> **只能是非成员函数**,因为左操作数是 std::ostream/std::istream,你不能给标准库类加成员

返回值类型陷阱:别随便返回 void 或局部对象

运算符语义决定了返回什么:

  • operator+= 应返回 *thisT&),支持链式调用:a += b += c;
  • operator+ 应返回 T(值语义),不是 T&——否则可能返回局部对象引用,导致悬垂引用
  • operator[] 通常返回 T&(非常量版本)和 const T&(常量版本),否则无法对元素赋值或在 const 对象上调用
  • operator== 必须返回 bool,且建议声明为 const 成员或接受两个 const T&

后置递增(operator++(int))怎么写才不翻车?

后置递增必须带 int 形参(仅作标记,不使用),且行为上要「先返回旧值,再自增」:

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 对象上调用——这不是警告,是硬性编译失败。

猜你喜欢

联络方式:

400 9058 355

邮箱:8955556@qq.com

Q Q:8955556

微信二维码
在线咨询 拨打电话

电话

400 9058 355

微信二维码

微信二维码