运算符重载的本质是函数重载。

语法格式
重载函数的一般格式如下:
返值类型operator运算符名称(形参表列)
{
;
}
operator运算符名称在一起构成了新的函数名。比如
constComplexoperator+(constComplex&c1,constComplex&c2);
我们会说,operator+重载了重载了运算符+。

如果是能够连续使用的运算符,一般会返回他自己的引用或者他自身,比如=,<<这种在一个语句中可以重复使用的

javascript运算符重载 运算符重载const_javascript运算符重载

 

javascript运算符重载 运算符重载const_javascript运算符重载_02

 

 

 同时也只有自身能够返回引用,因为this不是一个局部变量,其他局部变量不能这样做

 

运算符重载中一种常用的手段是友元重载,因为运算符一般使用全局重载,友元重载能够帮助全局重载后的运算符能够正常使用类内的数据

javascript运算符重载 运算符重载const_类对象_03

(2,3)
(3,4)
(5,7)
(5,7)

重载规则
(1)C++不允许用户自己定义新的运算符,只能对已有的C++运算符进行重载。

(2)C++允许重载的运算符
C++中绝大部分运算符都是可以被重载的。

javascript运算符重载 运算符重载const_类对象_04

不能重载的运算符只有4个:

javascript运算符重载 运算符重载const_运算符_05

(3)重载不能改变运算符运算对象(即操作数)的个数。
例如,关系运算符“>”和“<”等是双目运算符,重载后仍为双目运算符,需要两个参数。运算符”+“,”-“,”*“,”&“等既可以作为单目运算符,也可以作为双目运算符,可以分别将它们重载为单目运算符或双目运算符。
(4)重载不能改变运算符的优先级别。
例如”*“和”/“优先级高于”+“和”-“,不论怎样进行重载,各运算符之间的优先级不会改变。有时在程序中希望改变某运算符的优先级,也只能使用加括号的方法强制改变重载运算符的运算顺序。
(5)重载不能改变运算符的结合性。
如,复制运算符”=“是右结合性(自右至左),重载后仍为右结合性。
(6)重载运算符的函数不能有默认的参数
否则就改变了运算符参数的个数,与前面第(3)点矛盾。
(7)重载运算符的运算中至少有一个操作数是自定义类。
重载的运算符必须和用户定义的自定义类型的对象一起使用,其参数至少应有一个是类对象(或类对象的引用)。也就是说,参数不能全部是C++的标准类型,防止将原有的的默认实现抵消

(8)不必重载的运算符(=&)
用于类对象的运算符一般必须重载,但有两个例外,运算符”=“和运算符”&“不必用户重载。
复制运算符”=“可以用于每一个类对象,可以用它在同类对象之间相互赋值。因为系统已为每一个新声明的类重载了一个赋值运算符,它的作用是逐个复制类中的数据成员 地址运算符&也不必重载,它能返回类对象在内存中的起始地址。

(9)对运算符的重载,不应该失去其原有的意义
应当使重载运算符的功能类似于该运算符作用于标准类型数据时候时所实现的功能。例如,我们会去重载”+“以实现对象的相加,而不会去重载”+“以实现对象相减的功能,因为这样不符合我们对”+“原来的认知。

 

总结

1.重载格式

javascript运算符重载 运算符重载const_类对象_06

 

i++

constComplexoperator++(int);

friendconstComplexoperator++(Complex&c,int);//哑元

++i

Complex&operator++(); 

friendComplex&operator++(Complex&c);

2.只能重载为成员函数的

javascript运算符重载 运算符重载const_类对象_07

 

 3.常规建议

javascript运算符重载 运算符重载const_javascript运算符重载_08

 

4.友元还是成员?
假设,我们有类Sender类和Mail类,实现发送邮件的功能。
Sendersender;Mailmail;
sender<<mail;

sender左操作数,决定了operator<<为Sender的成员函数,而mail决定了operator<<要作Mail类的友员。因为sender是实际操作<<运算符的类,所以<<要作为他的成员函数来使用,而mail是被操作的类,要保证mail类中的数据对于重载的<<可调用,所以该函数是他的友元。

javascript运算符重载 运算符重载const_运算符_09

结论:
1,一个操作符的左右操作数不一定是相同类型的对象,这就涉及到将该操作符函数定义为谁的友元,谁的成员问题。
2,一个操作符函数,被声明为哪个类的成员,取决于该函数的调用对象(通常是左操作数)。

3.一个操作符函数,被声明为哪个类的友员,取决于该函数的参数对象(通常是右操作数)

4.而二元运算符因为两个变量都是被操作符也都是操作符,所以设置一个成员,一个友元太麻烦,一般直接设置非成员函数并且做两个友元