运算符重载
提出背景
C++中的基本类型可以使用+,-
等运算符对其直接进行操作,这样非常方便。但是默认情况下不能直接用运算符对对象进行操作。例如:
class Stock{
private:
double price;
public:
Stock(double);
Stock();
};
对于这个类的对象,如果我们想将两个对象的price
成员的值相加,就只能定义一个sum()
函数来实现操作。这样我们在使用的时候也要调用这个函数。注意运算符的左侧为调用对象,右边是被调用的对象
。
但是通过重载运算符,我们可以直接将这个操作用操作符来表示,例如:
Stock s1(23);
Stock s2(34);
Stock s = s1 + s2;
这样可以使代码更加整洁优雅。
基本语法
运算符的重载有两种实现方法,一种是在类内实现,另一种是在类外通过友元的方式实现。
在类内实现的格式为:
returnType operatorop (argumentList)
其中op
就是需要重载的运算符,在实际应用中的实例为:
class Stock{
private:
double price;
public:
Stock(double);
Stock();
Stock operator+(Stock s) const;
};
Stock Stock::operator+(Stock s) const{
return Stock(price + s.price);
}
这样就能直接用+
运算符对Stock
类进行运算,如:
Stock x = Stock(23);
Stock y(23);
Stock z = x + y;
运算符重载的本质是一个函数,当编译器检测到运算符的操作数是Stock
类时,就会自动调用对应的运算符重载函数。
另一个实现运算符重载的方式是在类外实现,利用友元
的方式。在有些情况下,类内实现的方式不能满足需求。例如,对于这种情况:
Stock s1(23);
Stock s = 2 * s1;
注意运算符的左边是调用对象,这时调用对象int
需要访问s1
中的price
对象,但是price
是一个private
对象,不能被直接访问,这时就需要利用友元的方式实现运算符的重载,从而让int
对象可以直接访问Stock
对象中的private
成员。其语法为:
class Stock{
//声明一个函数为该类的友元函数
friend Stock operator*(double,const Stock &);
}
//定义函数的时候不需要加friend关键字
Stock operator*(double m, const Stock & s){
return Stock(m * s.price);
}
重载运算符的限制
在对运算符进行重载的时候有一些需要注意的点:
- 重载后的运算符必须至少有一个操作数是用户定义的类型,这将防止用户为标准类型重载运算符。
- 使用运算符时不能违反运算符原来的语法规则。也就是说对运算符重载之后不能改变原来运算符的用法,例如二元操作符不能重载成一元操作符,重载之后运算符的优先级不能改变。
- 不能创建新的运算符,例如不能定义
s1 @ s2
。 - 下列运算符只能通过成员函数在类内重载:
=
,()
,[]
,->
。