492 字
1 分钟
【CPP】运算符重载
整理自 0324.md,已校对并补充示例与选择建议。
目的
让自定义类型能像内置类型一样使用 +、-、<< 等运算符,提高可读性并封装逻辑。
基本规则
- 至少有一个操作数是用户定义类型(类、枚举、模板实例等)。
- 不能创造新运算符,只能重载已有运算符。
- 不能改变优先级与结合性。
- 不能改变操作数个数(元数)。
- 不能重载的运算符:
::、.、.*?:sizeof、typeid、alignof(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 + b 与 b + 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类似,谨慎重载可隐式转换的运算符。
分享
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时
相关文章 智能推荐
