在之前的的文章中介绍过函数重载,已经接触到重载(overloading)这个名词。所谓重载,就是重新赋予新的含义。函数重载就是对一个已有的函数赋予新的含义,使之实现新的功能。因此,同一个函数名就可以用来代表不同功能的函数,也就是一名多用。
运算符也可以重载。实际上,我们已经在不知不觉之中使用了运算符重载。例如,大家都已习惯于用加法运算符"+"对整数、单精度数和双精度数进行加法运算,如5+8,5.8+3.67等,其实,计算机处理整数、单精度数和双精度数加法的操作方法是不同的,由于C++已经对运算符"+"进行了重载,使"+"能适用于int,float,double类型的不同的运算。
又如,"<<"是C++的位运算中的位移运算符(左移),但在输出操作中又是与流对象cout配合使用的流插入运算符,">>"也是位移运算符(右移),但在输入操作中又是与流对象cin配合使用的流提取运算符。这就是运算符重载(operator overloading)。C++系统对"<<"和">>"进行了重载,用户在不同的场合下使用它们时,作用是不同的。对"<<"和">>"的重载处理是放在头文件stream中的。因此,如果要在程序中用"<<"和">>"作流插入运算符和流提取运算符,必须在本文件模块中包含头文件stream(当然还应当包括"using namespace std;")。
现在要讨论的问题是:用户能否根据自己的需要对C++已提供的运算符进行重载,赋予它们新的含义,使之一名多用。譬如,能否用"+"号进行两个复数的相加。若有c1=(3+4i),c2=(5-10i),在数学中可以直接用"+"号实现c3=c1+c2,即将c1和c2的实部和虚部分别相加,c3=(3+5,(4-10)i)=(8,-6i)。但在C++中不能在程序中直接用运算符"+"对复数进行相加运算。用户必须自己设法实现复数相加。
最容易想到的方法是:用户可以自己定义一个专门的函数来实现复数相加。
编写程序:
运行结果:
程序分析:
在Complex类中声明一个complex_add函数,此函数在类外定义,其作用是将两个复数相加,在该函数体中定义一个Complex类对象c作为临时对象。其后的两个赋值语句相当于
c.real=this->real+c2.real;
c.imag=this->imag+c2.imag;
this是当前对象的指针。this->real也可以写成(*this).real。现在,在main函数中是通过对象c1调用complex_add函数的,因此,以上两个语句相当于
c.real=c1.real+c2.real;
c.imag=c1.imag+c2.imag;
注意函数的返回值是Complex类对象c的值。
结果无疑是正确的,但调用方式不直观、太烦琐,使人感到很不方便。人们自然会想:能否也和整数的加法运算一样,直接用加号"+"来实现复数运算,如
c3=c1+c2;
编译系统就会自动完成c1和c2两个复数相加的运算。如果能做到,就为对象的运算提供很大的方便。这就需要对运算符"+"进行重载。