Appearance
运算符重载
- CPP 的运算符继承 C语言运算符 。
- 静态多态
算数类运算符
- 表达式 L#R
- L/R:可以是左值可以是右值
- 返回:同类型右值
- 格式:
- 类成员函数版:
const 类名 operator#(const 类名 &R) const- 第一个
const:返回值不允许修改(右值) - 第二个
const:R 不允许被修改 - 第三个
const:L 不允许被修改
- 第一个
- 全局函数版:
const 类名 operator#(const 类名 &L, const 类名 &R);
- 类成员函数版:
对于重载加号操作符
operator+,最好将返回值定义为对象类型而不是引用类型。这是因为operator+通常会创建一个新的对象,而不是修改原有的对象。如果将返回值定义为引用类型,那么会有以下两个问题:
1. 引用类型的返回值可能会指向一个临时对象
在operator+中,我们通常会创建一个新的对象,并返回该对象的副本。如果将返回值定义为引用类型,则该引用可能会指向一个临时对象,而临时对象在函数返回后将会被销毁。这样返回一个引用类型的对象是不安全的。
2. 引用类型的返回值可能会导致对象所有权的不确定性
在C++中,对象的所有权通常是清晰明确的。如果将返回值定义为引用类型,则该引用可能会指向另一个对象,这会导致对象所有权的不确定性。如果返回一个对象类型的对象,则可以清晰地知道该对象的所有权属于哪个变量或者对象。
赋值类运算符
- 表达式 L#R
- L 是左值,R 是右值
- 返回:自身的引用,左值
- 格式:
- 类成员函数版:
类名 & operator#(const 类名 &R) - 全局函数版:
类名 & operator#(类名 &L, const 类名 &R);
- 类成员函数版:
关系运算符
- 表达式 L#R
- L/R:可以是左值可以是右值
- 返回:右值,布尔值
- 格式:
- 类成员函数版:
bool operator#(const 类名 &R) const - 全局函数版:
bool operator#(const 类名 &L, const 类名 &R);
- 类成员函数版:
单目运算符
- 表达式
#O - O:可以是左值可以是右值
- 返回:有些返回左值有些返回右值
- 格式:
- 类成员函数版:
类名 operator#(void) const - 全局函数版:
类名 operator#(const 类名 &O);
- 类成员函数版:
自增运算符
- 前置
- 表达式
++O O:只能是左值- 返回:自身引用(左值)
- 格式:
- 成员函数版
类名 &operator++() - 全局函数版
类名 &operator++(类名 &O)
- 成员函数版
- 后置
- 表达式
O++ O:只能是左值- 返回:临时值,右值
- 格式:
- 成员函数版:
const 类名 operator++(int) - 全局函数版:
const 类名 operator++(类名 &other, int)
- 成员函数版:
- 哑元的类型可随意
插入和提取运算符
cin和cout是分别来自于<istream>和<ostream>的对象- 运算符
<<,>>的重载,需要涉及到上述对象,所以需要使用全局函数当作友元函数,不能设置成员函数 - 因不需要使用
<istream>和<ostream>私有成员,不须修改它们 - 因须使用自身私有成员,需要在自身类体内设置成友元函数
- 格式:
- 插入运算符:
ostream &operator<<(ostream &L, const 类名 &R) - 提取运算符:
istream &operatro>>(istream &L, const 类名 &R)
- 插入运算符:
[]运算符
不能重载的运算符
- 成员运算符
. - 成员指针运算符
.* - 三目运算符
? : - 求字节运算符
sizeof - 作用域限定符
::
注意事项
- 只能在语法已有的运算符上进行重载
- 不能改变运算符的优先级
- 不能改变运算符的结合律
- 不要改变运算符的本质(比如减法中实现加法)
- 一般不能设置默认参数