05-重载限制
11.2.2 重载限制
多数C++运算符(参见表11.1)都可以用这样的方式重载。重载的运算符(有些例外情况)不必是成员函数,但必须至少有一个操作数是用户定义的类型。下面详细介绍C++对用户定义的运算符重载的限制。
1.重载后的运算符必须至少有一个操作数是用户定义的类型,这将防止用户为标准类型重载运算符。因此,不能将减法运算符(−)重载为计算两个double值的和,而不是它们的差。虽然这种限制将对创造性有所影响,但可以确保程序正常运行。
2.使用运算符时不能违反运算符原来的句法规则。例如,不能将求模运算符(%)重载成使用一个操作数:
int x;
Time shiva;
% x; // invalid for modulus operator
% shiva; // invalid for overloaded operator
同样,不能修改运算符的优先级。因此,如果将加号运算符重载成将两个类相加,则新的运算符与原来的加号具有相同的优先级。
3.不能创建新运算符。例如,不能定义operator **()函数来表示求幂。
4.不能重载下面的运算符。
- sizeof:sizeof运算符。
- .:成员运算符。
- . *:成员指针运算符。
- :::作用域解析运算符。
- ?::条件运算符。
- typeid:一个RTTI运算符。
- const_cast:强制类型转换运算符。
- dynamic_cast:强制类型转换运算符。
- reinterpret_cast:强制类型转换运算符。
- static_cast:强制类型转换运算符。
然而,表11.1中所有的运算符都可以被重载。
5.表11.1中的大多数运算符都可以通过成员或非成员函数进行重载,但下面的运算符只能通过成员函数进行重载。
- =:赋值运算符。
- ():函数调用运算符。
- [ ]:下标运算符。
- ->:通过指针访问类成员的运算符。
注意: 本章不介绍这里列出的所有运算符,但附录E对本书正文中没有介绍的运算符进行了总结。
| + | - | | / | % | ^ | | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | | & | | | ~= | ! | = | < | | > | += | -= | = | /= | %= | | ^= | &= | |= | << | >> | >>= | | <<= | == | != | <= | >= | && | | || | ++ | −− | , | −>* | −> | | () | [] | new | delete | new [] | delete [] |
除了这些正式限制之外,还应在重载运算符时遵循一些明智的限制。例如,不要将*运算符重载成交换两个Time对象的数据成员。表示法中没有任何内容可以表明运算符完成的工作,因此最好定义一个其名称具有说明性的类方法,如Swap()。