所谓重载就是赋予新的含义。函数重载可以让一个函数名有多种功能,在不同情况下进行不同的操作。运算符重载也是这个道理,同一个运算符可以有不同的功能。
C++允许程序员自己重载运算符。下面代码定义了一个复数类,通过运算符重载,用“+”号实现了复数的加法运算:
#include <iostream>
using namespace std;
class complex{
private:
double real; //实部
double imag; //虚部
public:
complex() : real(0.0), imag(0.0){ }
complex(double a, double b) : real(a), imag(b){ }
complex operator+(const complex & A)const;
void display()const;
};
//运算符重载
complex complex::operator+(const complex & A)const{
complex B;
B.real = real + A.real;
B.imag = imag + A.imag;
return B;
}
void complex::display()const{
cout << real << " + " << imag << "i" << endl;
}
int main(){
complex c1(4.3, 5.8);
complex c2(2.4, 3.7);
complex c3;
c3 = c1 + c2;
c3.display();
return 0;
}
运行结果:
上面的代码定义了一个复数类,real表示实部,imag表示虚部。运算符重载的方式就是定义一个函数,在函数体内实现想要的功能,当用到该运算符时,编译器会自动调用这个函数。也就是说,运算符重载是通过函数定义实现的,它本质上是函数重载。
运算符重载的格式为:
返回值类型 operator 运算符名称 (形参表列){
//TODO:
}
operator是关键字,用于定义重载运算符的函数。
例如,要在全局范围内重载"+",实现复数加法运算,可以这样来定义:
complex operator+(const complex &A, const complex &B){
complex C;
C.real = A.real + B.real;
C.imag = A.imag + B.imag;
return C;
}
可以发现,函数名由 operator 和操作符组成,上面的”operator+“就是函数名。重载运算符的函数除了函数名有特定的格式,其他地方和普通函数没有区别。
上面的例子中,我们在类 Complex 中重载了运算符"+",该重载只对 Complex 对象有效。当执行c3 = c1 + c2;
语句时,编译器检测到"+"号左边("+"号具有左结合性)是一个 Complex 对象,就会调用运算符重载函数,该语句会被转换为:
c1.operator+(c2);很明显是一个函数调用。
上面的运算符重载还可以有更加简练的定义形式:
complex complex::operator+(const complex & A)const{
return complex(real+A.real, imag+A.imag);
}
return 语句中的
complex(real+A.real, imag+A.imag)
会创建一个临时对象,它没有对象名,是一个匿名对象。在创建临时对象过程中调用构造函数,return 语句将该临时对象作为函数返回值。
虽然重载运算符所实现的功能完全可以用函数替代,但运算符重载使得程序的书写更加人性化,易于阅读。运算符被重载后,原有的功能仍然保留,没有丧失或改变。通过运算符重载,扩大了C++已有运算符的功能,使之能用于类对象。