运算符重载是C++极为重要的语言特性之一,本文将用代码实例回答――C++哪些运算符可以重载?如何重载?实现运算符重载时需要注意哪些?
哪些运算符可以重载,哪些不可重载?
C++98,C++0x,C++11对“哪些运算符重载可以重载”有一致的规定,具体如下:

其中,很少使用的是“,”(逗号运算符)。<??http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PGJyPgo8L3A+CjxwPrHq17zNrNH5uea2qMHLPHN0cm9uZz6yu7/J1tjU2LXE1MvL47f7PC9zdHJvbmc+o7o8L3A+CjxwPjxpbWcgc3JjPQ=="https://www.cppentry.com/upload_files/article/49/1_a35mr__.png" alt="\">
其中,“::”是作用域运算符,
“?:”是条件运算符。
两个较少使用的运算符是 .* 和 ->* 分别是:
.* 对象调用成员函数指针;
->* 对象指针调用成员函数指针;
标准还指出,有的运算符可以同时支持“一元运算”和“二元运算”:

下文通过实现几个模拟内置类型的类来展示具体的运算符重载方法应当如何实现。
一些注意事项
实现运算符重载时应注意:
运算符重载
不改变运算符的优先级与结合性,如/的优先级比-高;运算符重载
不改变部分运算符对操作数个数的限制,如+只能有两个操作数;
模拟整型Integer
回想一下C++里整型支持支持那些运算?具体有:
算术运算:
正,如 +a;负,如 -a;
加,如 a + b;减,如 a - b;乘,如 a * b;除,如 a / b;取余(模),如 a % b;
自增自减(整型特有):
自增,如 a++,++a;自减,如 a--,--a;
比较运算:
大于,如 a > b;小于,如 a < b;
等于,如 a == b;不等于,如 a != b;
大于等于,如 a >= b;小于等于,如 a <= b;
位运算:
按位取反,如 ~a;
左移,如 a << 2;右移,如 a >> 3;
按位与,如 a & b;按位或,如 a " b;按位异或,如 a ^ b;
赋值运算:
赋值,a = 5;
复合赋值:
+=,-=,*=,/=,%=,(算数运算与赋值运算复合)
&=,|=,^=,<<=,>>=,(位运算与赋值运算复合)
下面是这个Integer的代码:
class Integer
{
public:
Integer(int ival) : value(ival) {}
Integer(const Integer& iobj) : value(iobj.value) {}
// operator int() { return value; } // conversion to built-in int
Integer operator+() const { return Integer(value); }
Integer operator-() const { return Integer(-value); }
Integer operator+(const Integer& rhs) const { return Integer(value + rhs.value); }
Integer operator-(const Integer& rhs) const { return Integer(value - rhs.value); }
Integer operator*(const Integer& rhs) const { return Integer(value * rhs.value); }
Integer operator/(const Integer& rhs) const { return Integer(value / rhs.value); }
Integer operator%(const Integer& rhs) const { return Integer(value % rhs.value); }
// prefix
Integer operator++() { return Integer(++value); }
Integer operator--() { return Integer(--value); }
// suffix
Integer operator++(int) { int old = value; value++; return Integer(old); }
Integer operator--(int) { int old = value; value--; return Integer(old); }
// compare:
bool operator<(const Integer& rhs) const { return value < rhs.value; }
bool operator>(const Integer& rhs) const { return value > rhs.value; }
bool operator==(const Integer& rhs) const { return value == rhs.value; }
bool operator!=(const Integer& rhs) const { return value != rhs.value; }
bool operator<=(const Integer& rhs) const { return value <= rhs.value; }
bool operator>=(const Integer& rhs) const { return value >= rhs.value; }
// bit operations:
Integer operator~() const { return Integer(~value); }
Integer operator<<(unsigned n) const { return Integer(value << n); }
Integer operator>>(unsigned n) const { return Integer(value >> n); }
Integer operator&(const Integer& rhs) const { return Integer(value & rhs.value); }
Integer operator|(const Integer& rhs) const { return Integer(value | rhs.value); }
Integer operator^(const Integer& rhs) const { return Integer(value ^ rhs.value); }
// assignment:
Integer operator=(const Integer& rhs) { return value = rhs.value; }
// compound assignment:
Integer operator+=(const Integer& rhs) { return value += rhs.value; }
Integer operator-=(const Integer& rhs) { return value -= rhs.value; }
Integer operator*=(const Integer& rhs) { return value *= rhs.value; }
Integer operator/=(const Integer& rhs) { return value /= rhs.value; }
Integer operator%=(const Integer& rhs) { return value %= rhs.value; }
Integer operator&=(const Integer& rhs) { return value &= rhs.value; }
Integer operator|=(const Integer& rhs) { return value |= rhs.value; }
Integer operator^=(const Integer& rhs) { return value ^= rhs.value; }
Integer operator<<=(const Integer& rhs) { return value <<= rhs.value; }
Integer operator>>=(const Integer& rhs) { return value >>= rhs.value; }
// private:
int value;
};
实现运算符重载函数时,需要注意的是末尾是否要加const?
这取决与操作是否会改变当前对象的成员值,如果不改变则不加,改变则加。
Integer类只是为了展示如何使用运算符重载,并没有多少实用价值。
一下是Integer类的测试:
void testInteger()
{
Integer i = 123;
#define SEPRATER ":\t"
#define TRACE_INTEGER(iobj) printf(#iobj SEPRATER "%d\n", (iobj).value)
#define TRACE_BOOL(exp) printf(#exp SEPRATER "%s\n", (exp) ? "true" : "false")
#define TRACE_HEX(iobj) printf(#iobj SEPRATER "%p\n", (iobj).value)
TRACE_INTEGER(i);
TRACE_INTEGER(+i);
TRACE_INTEGER(-i);
Integer j = 5;
TRACE_INTEGER(i+j);
TRACE_INTEGER(i-j);
TRACE_INTEGER(i*j);
TRACE_INTEGER(i/j);
TRACE_INTEGER(i%j);
TRACE_INTEGER(++i