运算符重载
重载意义
在C++预定义中,运算符的操作对象只局限于基本的内置数据类型(int、double…),但是对于我们自定义的类型(类)是无法完成对应操作的。当我们对自定义的类型也有类似操作需求时,便需要对运算符进行不同的定义,赋予其新的功能,通过参数的类型及个数来区分,完成重载。
重载格式:
<返回类型说明符> operator <运算符符号>(<参数表>)
{
<函数体>
}
重载限制
重载运算符的基本原则:
- C++规定重载后的运算符的操作对象必须至少有一个是用户定义的类型
- 使用运算符时不能违反运算符原来的句法规则。
例如:不能将求模运算符(%)重载成使用一个操作数;不能修改运算符的优先级等…
- 不能创建新的运算符。
例如:不能定义operator**()函数来表示求幂
- 不能重载下面的运算符:
.* //成员指针运算符
:: //作用域解析运算符
sizeof //sizeof运算符
?: //条件运算符
. //成员运算符
- 以下运算符只能通过成员函数进行重载
= //赋值运算符
() //函数调用运算符
[] //下标运算符
-> //通过指针访问类成员的运算符
为何=、()、[ ]、->只能通过成员函数重载:
原因很简单,会和编译器默认分配的运算符重载成员函数冲突,引发歧义。我们知道友元函数不是类的成员函数,它只是类的“朋友“,具有访问把它声明为“朋友”的类的数据成员的权限而已。那么当把赋值运算符重载为类的友员函数,在程序中执行类对象的赋值语句时,程序就会出现两种矛盾的选择。因为它认为类中并没有重载赋值运算符的成员函数,所以它根据C++的规则,会去调用相应的构造函数。但是在全局里,我们已经重载了参数类型为此类类型的赋值运算符函数,而这赋值语句刚好和这函数匹配上了,根据C++的规则,也会去调用这函数。故出现二义性。