492 字
1 分钟
【CPP】运算符重载
2026-03-24

整理自 0324.md,已校对并补充示例与选择建议。

目的#

让自定义类型能像内置类型一样使用 +-<< 等运算符,提高可读性并封装逻辑。

基本规则#

  1. 至少有一个操作数是用户定义类型(类、枚举、模板实例等)。
  2. 不能创造新运算符,只能重载已有运算符。
  3. 不能改变优先级与结合性。
  4. 不能改变操作数个数(元数)。
  5. 不能重载的运算符:
    • ::..*
    • ?:
    • sizeoftypeidalignof(C++11 起)
    • .* 等成员访问相关

成员函数 vs 非成员函数#

形式一元运算符二元运算符
成员函数无显式参数(this 为操作数)一个显式参数(this 为左操作数)
非成员函数一个参数两个参数

“元”:操作数的个数。一元一个,二元两个。

必须以成员函数重载#

  • = 赋值
  • () 函数调用
  • [] 下标
  • -> 成员访问(箭头)

建议用非成员 friend 或自由函数重载#

  • 二元运算符且需要左操作数不是本类(如 cout << obj):
class Point {
int x, y;
friend std::ostream& operator<<(std::ostream& os, const Point& p);
public:
Point(int x, int y) : x(x), y(y) {}
};
std::ostream& operator<<(std::ostream& os, const Point& p) {
return os << '(' << p.x << ',' << p.y << ')';
}

选择建议(原笔记“什么情况用哪种”)#

场景推荐
修改左操作数且左操作数是本类成员(如 +=
对称二元运算(a + bb + a非成员,常配合 friend
需要支持隐式转换的一侧在左非成员
=[]()->成员

常见示例#

一元 ++#

class Counter {
int n = 0;
public:
Counter& operator++() { ++n; return *this; } // 前置
Counter operator++(int) { Counter tmp = *this; ++n; return tmp; } // 后置
};

二元 +#

class Vec2 {
public:
double x, y;
Vec2 operator+(const Vec2& rhs) const {
return {x + rhs.x, y + rhs.y};
}
};

赋值 =#

编译器生成的拷贝/移动赋值在多数情况下够用;涉及资源管理时需自定义,并注意自赋值拷贝交换惯用法

Widget& operator=(const Widget& rhs) {
if (this == &rhs) return *this;
// 释放旧资源,深拷贝 rhs
return *this;
}

注意#

  • 重载不改变内置类型运算:int + int 仍按内置规则。
  • 不要为炫技重载 &&||(会失去短路求值)。
  • explicit 类似,谨慎重载可隐式转换的运算符。
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

【CPP】运算符重载
https://lysj.work/posts/studynotes/cpp/cpp运算符重载/
作者
Sekiro
发布于
2026-03-24
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录