《C++ Primer Plus》11. 使用类
运算符重载
可重载的运算符:
类型 | 运算符 |
---|---|
双目算术运算符 | + 、- 、* 、/ 、% |
关系运算符 | || 、&& 、! |
单目运算符 | + (正)、- (负)、* (解引用)、& (取地址) |
位运算符 | | 、& 、~ 、^ 、<< 、>> |
赋值运算符 | = 、+= 、*= 、/= 、%= 、&= 、|= 、^= 、<<= 、>>= |
空间申请与释放 | new 、delete 、new[] 、delete[] |
其他运算符 | () (函数调用)、-> (成员访问)、, (逗号)、[] (下标) |
不可重载的运算符:
.
:成员访问运算符.*
、->*
:成员指针访问运算符::
:域运算符sizeof
:长度运算符?:
:三目条件运算符#
:预处理符号
运算符重载有两种形式:成员函数重载和非成员函数重载(友元),其中有一部分运算符只能通过成员函数进行重载:
=
:赋值运算符()
:函数调用运算符[]
:下标运算符->
:通过指针访问类成员的运算符
在重载运算符时,只能选择其中一种形式,而不能同时选择
运算符重载必须至少有一个操作数是用户定义的类型(不需要都是),返回值可以任意,但必须满足 C++ 的类型系统约束
友元
有三种:友元函数、友元类、友元成员函数
需要友元的一个场景是不同类型之间的运算符重载,例如 A = 3 * B
,我们必须构造一个函数 T operator*(int x, const T & y)
将函数放到类的声明中,并且加上 friend
就能声明一个友元函数:
friend T operator*(int x, const T & y);
- 虽然这个函数在类声明中声明,但是它不是成员函数,因此不能使用成员运算符(
.operator*
)调用 - 虽然它不是成员函数,但是它与成员函数的访问权限相同
实现这个友元函数时,无需限定类作用域(不需要 T::
)
类的自动转换和强制类型转换
- 从其他类型转换到当前类:使用单参数构造函数
- 从当前类转换到其他类型:使用转换函数
operator int();
、operator double();
、operator T2();
等
如果在构造函数前或者转换函数前添加 explicit
,那么就只能显式转换,否则可以隐式转换
注意转换函数没有返回类型和参数,但必须返回值
经验表明,最好不要依赖这种隐式转换