8.3 运算符重载的限制
C++ 中的大部分运算符都可以被重载。图 8.1 列出了可以被重载的运算符,图 8.2 列出了不能被重载的运算符。
常见编程错误 8.1
想重载不能重载的运算符是个语法错误。
可以重载的运算符
+ - * / % ^ & |
~ ! = < > += -= *=
/= %= ^= &= |= << >> >>=
<<= == != <= >= && || ++
-- ->* , -> [] () new delete
new[] delete[]
图 8.1 可以被重载的运算符
不可以重载的运算符
. .* :: ?: sizeof
图 8.2 不能被重载的运算符
重载不能改变运算符的优先级。虽然重载具有固定优先级的运算符可能会不便于使用,但是在表达式中使用圆括号可以强制改变重载运算符的计算顺序。
重载不能改变运算符的结合律。
重载不能改变运算符操作数的个数。重载的一元运算符仍然是一元运算符,重载的二元运算符仍然是二元运算符,C++中的惟一的三元运算符(?:)也不能被重载。运算符&、*、+和-既可以用作一元运算符,也可以用作二元运算符,可以分别把他们重载为一元运算符和二元运算符。
不能创建新的运算符,只有现有的运算符才能被重载。因此,程序员不能使用一些流行的表示方法,如BASIC中表示指数的运算符**。
常见编程错误 8.2
试图创建新的运算符是个语法错误。
运算符重载不能改变该运算符用于内部类型对象时的含义。例如,程序员不能改变运算符+用于两个整数时的含义。运算符重载只能和用户自定义类型的对象一起使用,或者用于用户自定义类型的对象和内部类型的对象混合使用时。
常见编程错误 8.3
试图改变运算符对内部类型的对象的作用方式是个浯法错误。
软件工程视点 8.2
运算符函数的参数至少有一个必须是类的对象或者是对类的对象的引用。这种规定防止了程序员改变运算符对内部类型的对象的作用方式。
重载了赋值运算符=和加法运算符+以后,虽然下列语句是允许的:
object2 = object2 + object1;
但并不意味运算符+=也被自动重载了。因此,下面的语句是不允许的:
object2 += object1;
然而,显式地重载运算符 +=
可使上述语句成立。
常见编程错误 8.4
认为重载了某个运算符(如 +
)可以自动地重载相关的运算符(如 +=
),或重载了 ==
就自动重载了 !=
,运算符只能被显式重载(不存在隐式重载)。
常见编程错误 8.5
想通过运算符重栽改变运算符的 数量 是个语法错误。
编程技巧 8.5
要保证相关运算符的一致性,可以用一个运算符实现另一个运算符(即用重载的运算符 +
实现重载的运算符 +=
)。