企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## 一.总则 1. 对于类类型,重载运算符一般使用 **引用** 作为参数,来避免不必要的复制。 2. 为了增加对 **常对象** 的支持,建议将 类类型参数 设置为 **常引用** ,对于在类内重载的运算符,可以将该函数设置为 **常成员函数** 。 3. 返回值不一定是 **引用** ,更不能是局部变量的引用(除了 **引用参数** )。 ## 二.重载算术运算符(位运算符类似) 1. 算术运算符的操作细节:将计算结果放入新的对象,并返回。 **注意不要返回引用。** 2. 一般将双目算术运算符重载为友元或普通函数,将单目算术运算符重载为成员函数。 3. 一般情况下,算术运算符中 `+` 和 `*` 需要满足不同类型之间的交换律。为了满足这个需求,一般需要: + 重载为友元或普通函数。因为将这些运算符重载为普通函数,要求第一个操作数必须是该类的对象。 + 添加 **转换构造函数** ,使得其他类型的数据可以转换到该类。 ```c++ //重载示例 T1 operator+(const T1&,const T2&); T1 operator+(const T2&,const T1&); //如果你的类有转换构造函数,可以把T2 转换成 T1,也可以这么写: T1 operator+(const T1&,const T1&); ``` 4. 注意除法和取余中,第二个操作数为 `0` 的情况。 ## 二.重载赋值运算符 1. 为满足 **链式调用** 的需求,应该设置返回值为第一个操作对象的引用。 2. 只能将该运算符重载为成员函数。 3. 一般不需要定义常成员函数版本。你会对一个常量赋值嘛? ```c++ //链式调用 a=b=c=d=e; //拷贝赋值运算符重载示例 T& T::operator=(const T&); //[11+][$]移动赋值运算符重载示例 T& T::operator=(const T&&); ``` ## 三.重载复合赋值运算符 1. 复合赋值运算符的操作细节:将计算结果放入第一个运算对象,并返回 **其引用** 。 2. 一般将复合赋值运算符重载为成员函数。 3. 注意除法和取余中,第二个操作数为 `0` 的情况。 4. 一般不需要定义常成员函数版本。你会对一个常量赋值嘛? ```c++ //链式调用 a+=b; //重载示例 T& T::operator+=(const T2&); ``` ## 四.重载关系运算符 1. 因为这些运算符功能几乎差不多,因此可以先写一个专用函数用于比大小。 例如,大于返回1,等于返回0,小于返回 -1。 然后这些重载函数的内容基本上就是一句话的事。 2. 返回值应该为 `bool` 。 ```c++ int T::compare(const T&) const; bool operator>(const T& t1,const T& t2) { return t1.compare(t2) > 0; } bool operator<(const T& t1,const T& t2) { return t1.compare(t2) < 0; } bool operator==(const T& t1,const T& t2) { return t1.compare(t2) == 0; } ``` ## 五.重载前置递增递减运算符 1. 一般类内重载前置递增递减运算符,不需要伪参数。 2. **需要返回递增后自身的引用** 。 3. 一般不需要定义常成员函数版本。你会对一个常量递增递减嘛? ```c++ //重载 T& T::operator++(); T& T::operator--(); //调用 T i; ++i; --i; ``` ## 六.重载后置递增递减运算符 1. 一般类内重载后置递增递减运算符。 2. 为了区分前置递增递减运算符,需要加上一个 **伪参数** 。 3. **需要返回递增递减前的自身** 。 4. 一般不需要定义常成员函数版本。你会对一个常量递增递减嘛? ```c++ //返回递增递减前的自身对象 T T::operator++(int); T T::operator--(int); //调用 T i; i++; i--; ``` ## 七.重载数组下标运算符 1. 只能重载为成员函数。 2. 可以通过赋值语句来修改运算结果并影响到对象自身,因此需要返回 **引用** 。 3. 注意检查下标范围。 ```c++ T& T::operator[](int); const T& T::operator[](int) const; ``` ## 八.重载解引用运算符 1. 运算结果为一个 **左值** ,因此需要返回引用。 ```c++ T& T::operator*(); const T& T::operator*() const; ``` ## 九.重载指针的成员运算符 1. 该运算符非常特殊,虽然它是双目运算符,但它的重载函数 **没有参数**。 2. 返回值为一个可以进行 **指针的成员访问** 的指针。 3. 必须在类内重载。 ```c++ //注: T1* 可以进行 `->` 操作 T1* T::operator->(); const T1* T::operator->() const; //相当于: t1.operator->()->t2; t1->t2; ``` ## 十.重载函数调用运算符 1. 效果:可以像函数一样使用对象。 2. 只能在类内重载。 ```c++ int T::operator()(int i,double d); ``` ## 十一.重载插入和提取运算符 只能在类外重载。 ```c++ ostream& operator<<(ostream& os,const T& obj); istream& operator>>(istream& is,T& obj); ``` ## 十二.罕见的运算符重载 1. `&(取地址)` 没有必要重载,因为它可以作用于任何类型的左值,表示取地址。 2. `,(逗号)` 可能会改变运算符本身的求值顺序。重载有负作用。 3. **逻辑运算符** 会失去其短路求值的特性。考虑到其负作用,一般使用类类型到 `bool` 的类型转换来代替逻辑运算符的重载。 4. `->*(指针的成员指针)` 。没有什么问题,但很少有类使用它。