运算符重载
我们平时用的加减乘除(1 + 1, 1 - 1, 1 * 1, 1 / 1),其实对于一些复杂的结构来说并不适用。。。
比如:
class Complex{
public:
Complex(){//构造函数
real = 0;
imag = 0
}
Complex(double r, double i){//构造函数
real = r;
imag = i;
}
void disp(){...}
};
这样的一个结构,如果两个对象进行相加,那么就不能简单的1 + 1了。
我们需要用到运算符重载:
class Complex{
public:
Complex(){//构造函数
real = 0;
imag = 0
}
Complex(double r, double i){//构造函数
real = r;
imag = i;
}
friend Complex operator + (Complex& c1, Complex& c2); //新增的内容
void disp(){...}
};
Complex operator + (Complex& c1, Complex& c2){ //新增的内容
return Comlpex(c1.real + c2.real, c1.image + c2.image); //新增的内容
}
这样其实就是把加法对Complex重新定义了一下子,便于这个类创建出的对象进行计算。
书面一点的说,运算符重载只能把一个运算符用于一个指定的类。
很明显,运算符重载是通过定义函数实现的,我们可以其实可以任意定义这种运算符的内容。
比如:我们可以把上面的加法内容写成:
Complex operator + (Complex& c1, Complex& c2){
return Comlpex(c1.real * c2.real, c1.image * c2.image);
}
这样做一个加法,实际上进行了乘法。
理论上,我们可以利用运算符重载执行任何操作,不过这样运算符重载就失去了意义,让人无法理解。
那么,平时看到的代码中,运算符可以重载为成员函数,有的却重载为友元函数。
一般地,运算符重载为友元函数或者重载为成员函数。
重载为成员函数:如果运算表达式中的第一个参数是一个类对象,且与运算符函数的类型相同。
重载为友元函数:如果有C++标准或者其他类的对象参与运算,且需要访问私有成员,就重载为友元函数。
如果左操作数为C++标准或者其他类的对象,只能作为非成员函数。
列几种情况作为参考:
1.一般将单目运算符和复合运算符(+=、-=、*=、/=......)重载为成员函数
2.一般讲双目运算符重载为友元函数
3.“<<”,“>>” 的重载只能作为友元函数
4.“=”, “[ ]”,“( )”, “->” 必须重载为成员函数(一般“=” 只在数据成员包含动态分配内存的指针成员才进行重载。。)
5.需要注意的是,对“++”, “--”的重载,增加一个int形参,就是后置自增/自减运算符函数。
为什么这么多规则呀?
1 #include<iostream>
2 using namespace std;
3
4 class Complex{
5 public:
6 Complex(){
7 real = 0;
8 imag = 0;
9 }
10 Complex(double r, double i){
11 real = r;
12 image = r;
13 }
14 Complex operator+(Complex &c2);
15
16 void diplay();
17 private:
18 double real;
19 double image;
20 }
21
22 Complex operator+(Complex &c2){
23 Complex c;
24 c.real = real + c2.real;
25 c.imag = imag + c2.imag;
26 return c;
27 }
28
29 void Complex::display(){
30 cout << "(" << real << "," << imag << "i)" << endl;
31 }
Q:加法的运算符重载为什么就一个参数呢?
A:这里可以理解为左操作数调用了operator+函数,右操作数作为参数传递给c2。
那么实际上,运算符重载函数右两个参数,第一个是隐含的this指针,其实就是左操作数。
Q:那么运算符重载只能把一个运算符适用于一个特定的类,那么如果Complex加上一个整形数据可以吗?
A:可以。但是无法利用上面定义的运算符重载,因为已经不适用了。需要重新定义,并且声明为友元函数。
这样容易理解了,为什么双目运算符和“>>”, “<<”重载为友元函数了。。
双目运算符一般重载为友元函数,因为可能有别的类对象或者C++标准类型参与;
“>>”, “<<”必须重载为友元函数,因为左操作数必须是istream或者ostream。