重载运算符
一,知识点总结
重载运算符函数可以对运算符做出新的解释,即定义用户所需要的各种操作。但运算符重载后,原有的基本语义不变,包括:
不改变运算符的优先级;
不改变运算符的结合性;
不改变运算符所需要的操作数;
不能创建新的运算符;
优先级和结合性主要体现在重载运算符的使用上,而操作数的个数不但体现在重载运算符的使用上,更关系到函数定义时的参数设定。
C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。
重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。
当您调用一个重载函数或重载运算符时,编译器通过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。选择最合适的重载函数或重载运算符的过程,称为重载决策。
重载运算符的限制
可以重载的运算符
+ - * / % ^ & | ~
! = < > += -= *= /= %
^= &= |= << >> >>= <<= == !=
<= >= && || ++ -- ->* ‘ ->
[] () new delete new[] delete[]
不能重载的算符
. :: .* ?: sizeof
重载格式:
函数类型 operator 要重载的运算符(形参表)
成员运算符函数的原型在类的内部声明格式如下:
class X {
//…
返回类型 operator运算符(形参表);
//…
}
在类外定义成员运算符函数的格式如下:
返回类型 X::operator运算符(形参表)
{
函数体
}
用成员函数重载运算符:
一元运算符: Object op
解释为:Object . operator op ()操作数由对象Object通过this指针隐含传递,括号里不用写形参,因为一元运算符只需要一个操作数,而这个操作数有对象Object通过this指针隐含传递。那要是二元运算符则括号里再加一个操作数。
二元运算符:ObjectL op ObjectR
解释为:
ObjectL . operator op ( ObjectR )
左操作数由ObjectL通过this指针传递,右操作数由参数ObjectR传递。
使用注意:重载 + 二元运算符,使用时可以a+b(隐式调用);就相当于a.operator+b(显式调用);前者使用起来比较方便。
用友元函数重载运算符:(因为友元函数里面没有this指针,和成员函数重载对比来说,要多一个操作数。)
一元运算符:Object op
解释为:
operator op (Object) 操作数由参数表的参数Object提供
二元运算符;ObjectL op ObjectR
解释为:
operator op ( ObjectL, ObjectR )
左右操作数都由参数传递
特殊运算符:①= () [] ->这些运算符只能用成员函数重载,不能用友元函数重载
②成员运算符函数比友元运算符函数少带一个参数(后置的++、--需要增加一个形参)。
③双目运算符一般可以被重载为友元运算符函数或成员运算符函数,但当操作数类型不相同时,必须使用友元函数。
④设A Aobject 运算符 ++和 - - 有两种方式:
前置方式: ++Aobject --Aobject
成员函数重载A :: A operator++ () ;
解释为:Aobject . operator ++( ) ;
友元函数重载friend A operator++ (A &) ;
解释为: operator ++( Aobject ) ;
后置方式: Aobject ++ Aobject --
成员函数重载 A :: A operator++ (int) ;
解释为: Aobject . operator ++( 0 ) ;
友元函数重载: friend A operator++ (A &, int) ;
解释为: operator++(Aobject, 0)
为了区别前置与后置,后置的时候多一个无关参数,比如上面的int,这些都可以表明是后置,他们在运行中没有其他的作用。
二 重载输入输出运算符
注意①输入输出运算符只能利用友元函数重载。
格式:输出运算符
ostream& operator<<(ostream& out,class_name& obj)
{
out<<obj.item1;
out<<obj.item2;
.. .
out<<obj.itemn;
return out;
}
输入运算符
istream& operator>>(istream& in,class_name& obj)
{
in>>obj.item1;
in>>obj.item2;
. . .
in>>obj.itemn;
return in;
}