【C++】C++中的操作符重载
C++中的操作符重载使得对于类对象的操作更加方便和直观,但是对于各种操作符重载的规则以及语法形式,一直以来都是用到哪一个上stackoverflow上查找,在查找了四五次之后,觉得每次麻烦小总结一下。
操作符重载的一般语法
重载方式分为两种,一种是重载为类的成员函数,另一种重载为类的友元函数,其语法形式分别为:
// 方式一:重载为成员函数 class MyClass { public: 返回类型 operator 操作符(形参列表); }; 返回类型 MyClass::operator 操作符(形参列表) { // 函数体 } // 方式二:重载为友元函数 class MyClass { public: friend 返回类型 operator 操作符(形参列表); }; 返回类型 operator 操作符(形参列表) { // 函数体 }
操作符重载的三条基本原则
- 如果操作符的含义并不显而易见或者有可能存在争议,不应该重载该操作符。考虑提供一个函数代替该操作符重载。
- 总是坚持操作符固有的语义。比如,如果将+操作符重载表示的语义a-b,编译器能够顺利通过,但是与操作符使用者的预期严重不符。
- 总是提供所有相关的操作符。比如,如果支持了a+b,使用者当然期望能够调用a+=b;如果支持前缀自增++a,同时提供后缀自增a--。如果提供了a<b,请提供a>b。
成员函数与非成员函数(友元函数)的选择
赋值操作符(=), 取下标操作符([]), 成员访问操作符(->)和函数调用操作符( () )必须重载为成员函数。
- 如果是一元操作符,实现为成员函数
- 如果是二元操作符,并且该二元操作符视左右操作数为平等的(例如:算数操作符,关系操作符和位操作符等),实现为非成员函数
- 如果是二元操作符,并且视左右操作数不平等,那么实现为成员函数(例如:+=,-=,*=, /=等)
常见的操作符重载
说了那么多,最重要的就是常见操作符的语法形式,如下:
#include <iostream> #include <string> using namespace std; class ClassType; // 输入输出操作符(必须为非成员函数) ostream& operator<< (ostream& os, const ClassType& object) {return os;} istream& operator>> (istream& is, ClassType& object) {return is;} // 注意object对象是非const引用 //赋值操作符(必须为成员函数) ClassType& operator= (const ClassType& object) {return *this;} ClassType& operator-= (const ClassType& object) {return *this;} ClassType& operator*= (const ClassType& object) {return *this;} ClassType& operator/= (const ClassType& object) {return *this;} ClassType& operator%= (const ClassType& object) {return *this;} // 算术操作符(一般定义为非成员函数) ClassType operator+ (const ClassType& lhs, const ClassType& rhs); ClassType operator- (const ClassType& lhs, const ClassType& rhs); ClassType operator* (const ClassType& lhs, const ClassType& rhs); ClassType operator/ (const ClassType& lhs, const ClassType& rhs); ClassType operator% (const ClassType& lhs, const ClassType& rhs); // 关系操作符(一般定义为非成员函数) inline bool operator< (const ClassType& lhs, const ClassType& rhs); inline bool operator<= (const ClassType& lhs, const ClassType& rhs); inline bool operator> (const ClassType& lhs, const ClassType& rhs); inline bool operator>= (const ClassType& lhs, const ClassType& rhs); inline bool operator== (const ClassType& lhs, const ClassType& rhs); inline bool operator!= (const ClassType& lhs, const ClassType& rhs); // 自增和自减操作符(一般作为成员函数) ClassType& operator++ () {return *this;} // 前缀++,例如:++iter ClassType& operator-- () {return *this;} ClassType operator++ (int) {return tmp;} // 后缀++,例如:iter++ ClassType operator-- (int) {return tmp;} // 下标操作符(必须定义为成员函数) TypeInContainer& operator[] (const size_t index) // 非const版本 const TypeInContainer& operator[] (const size_t index) const // const 版本 // 成员访问操作符(*,-> 定义成员函数) Class MyPtr { value_type& operator*(); //非const版本 const value_type& operator*() const; //const版本 value_type* operator->(); const value_type* operator->() const; }; // 函数调用操作符 struct MyClass { ClassType operator()(Type1 x1, Type2 x2) { } };
参考文献:
- Statckoverflow operator overloading discussion
- S.B.Lippman and J.Lajoie. C++ Primer中文版. 北京:人民邮电出版社, 2011. 430-453.
- 随感而发:C++操作符重载
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
2012-04-10 【编程之美】妙用位域解中国象棋将帅问题