重载运算符的意义:
C++中预定义的运算符的操作对象只能是基本数据类型。但实际上,对于许多用户自定义类型(例如类),也需要类似的运算操作。这时就必须在C++中重新定义这些运算符,赋予已有运算符新的功能,使它能够用于特定类型执行特定的操作。运算符重载的实质是函数重载。
定义:
运算符重载是通过创建运算符函数实现的,运算符函数定义了重载的运算符将要进行的操作。运算符函数的定义与其他函数的定义类似,惟一的区别是运算符函数的函数名是由关键字operator和其后要重载的运算符符号构成的。运算符函数定义的一般格式如下:
<返回类型说明符> operator <运算符符号>(<参数表>)
{
<函数体>
}
如何重载运算符
运算符函数重载一般有两种形式:重载为类的成员函数和重载为类的非成员函数。非成员函数通常是友元。
如果一个运算符函数是成员函数,则它的第一个(左侧)运算对象绑定到隐式的this指针上,因此,成员运算符函数的(显式)参数数量比运算符的运算对象总少一个(
class A{
private:
int a;
public:
A operator+(A&);
A()=default;
A(int x):a(x){}};
A A::operator+(A& d){
return A(a+d.a);
}int main()
{ A b,c,d;
d=b+c; //等价于d=b.operator+(c);
return 0;}
当运算符函数是非成员函数时,函数的参数与该运算符作用的运算对象数量一样多。
class A
{ private:
int a;
public:
friend A operator+(A&,A&);
A()=default;
A(int x):a(x){}
};
A operator+(A& c,A& d)
{
return A(c.a+d.a);
}
int main()
{
A b,c,d
d=b+c; //等价于d=operator+(b,c);
return 0;
}
两种重载形式的比较:
在多数情况下,将运算符重载为类的成员函数和类的友元函数都是可以的。但成员函数运算符与友元函数运算符也具有各自的一些特点:
- 赋值(=),下标([]),调用( ( ) ),和成员访问箭头(->)运算符必须是成员。
- 复合赋值运算符一般来说应该是成员,但并非必须,这一点与赋值运算符略有不同。
- 改变对象状态的运算符或者与给定类型密切相关的运算符,如递增,递减,和解引用运算符,通常应该是成员。
- 具有对称性的运算符可能转换任意一端的运算对象,例如算术,相等性,关系和位运算符等,因此它们通常应该是普通的非成员函数。
有些运算符可以重载有些不可以重载:
* 可以被重载的运算符 :
算术运算符:+ , - , * , / , % , ++ , –
位操作运算符:& , | , ~ , ^ , << , >>
逻辑运算符:! , && , ||
比较运算符:< , > , >= , <= , == , !=
赋值运算符:= , += , -= , *= , /= , %= , &= , |= , ^= , <<= , >>=
其他运算符:[] , () , -> , ,(逗号运算符) , new , delete , new[] , delete[] , ->*
下列运算符不允许重载:
. , .* , :: , ?: ,siezof
重载运算符注意事项:
(1)为了防止用户对标准类型进行运算符重载,C++规定重载后的运算符的操作对象必须至少有一个是用户定义的类型
这是什么意思呢?
比如说现在有两个数:int number1,int number2,
那么number1+number2 求的是两个数的和,
但是如果你重载以后让着两个数相加为他们的乘积,这肯定是不合乎逻辑的。
可能重载以后会有二义性,导致程序不知道该执行哪一个(是自带的的还是重载后的函数)
(2)使用运算符不能违法运算符原来的句法规则。如不能将% 重载为一个操作数,
例如:
int index;
%index;这种是不被允许的。
(3)不能修改运算符原先的优先级。
(4)不能创建一个新的运算符,例如不能定义operator** (···)来表示求幂
(5)不能进行重载的运算符:成员运算符,作用域运算符,条件运算符,sizeof运算符,typeid(一个RTTI运算符),const_cast、dynamic_cast、reinterpret_cast、static_cast强制类型转换运算符
(6)大多数运算符可以通过成员函数和非成员函数进行重载但是下面这四种运算符只能通过成函数进行重载:
= 赋值运算符,()函数调用运算符,[ ]下标运算符,->通过指针访问类成员的运算符。