C++中预定义的运算符的操作对象只能是基本数据类型,实际上,对于很多用户自定义类型,也需要有类似的运算操作。如果将C++中这些现存的运算符直接作用于用户自定义的类型数据上,会得到什么样的结果呢?编译器无法给出正常的结果,因为我们需要运算符重载,给运算符赋予多重含义,使同一个运算符作用于不同类型的数据导致不同类型的行为,增强了运算符的普适性。
运算符重载的实质是函数重载。在实现过程中,首先把指定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参,然后根据实参的类型来确定需要调用达标函数,这个过程在编译过程中完成。
运算符重载规则如下:
①、 C++中的运算符除了少数几个之外,全部可以重载,而且只能重载C++中已有的运算符。
②、 重载之后运算符的优先级和结合性都不会改变。
③、 运算符重载是针对新类型数据的实际需要,对原有运算符进行适当的改造。一般来说,重载的功能应当与原有功能相类似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型。
C++中只有五个运算符不能被重载,它们是:成员运算符“.”、指针运算符“*”、作用域运算符“::”、“sizeof”、条件运算符“?:”。
运算符重载形式有两种,重载为类的成员函数和重载为类的友元函数。
运算符重载为类的成员函数的一般语法形式为:
函数类型 operator 运算符(形参表) { 函数体; }
运算符重载为类的友元函数的一般语法形式为:
1 friend 函数类型 operator 运算符(形参表) 2 { 3 函数体; 4 }
其中,函数类型就是运算结果类型;operator是定义运算符重载函数的关键字;运算符是重载的运算符名称。
当运算符重载为类的成员函数时,函数的参数个数比原来的操作个数要少一个;当重载为类的友元函数时,参数个数与原操作数个数相同。原因是重载为类的成员函数时,如果某个对象使用重载了的成员函数,自身的数据可以直接访问,就不需要再放在参数表中进行传递,少了的操作数就是该对象本身。而重载为友元函数时,友元函数对某个对象的数据进行操作,就必须通过该对象的名称来进行,因此使用到的参数都要进行传递,操作数的个数就不会有变化。
运算符重载的主要优点就是允许改变使用于系统内部的运算符的操作方式,以适应用户自定义类型的类似运算。
二、运算符重载程序例子(成员函数方式)
1 //运算符重载:成员函数方式 2 #include <iostream> 3 using namespace std; 4 5 class complex //复数类 6 { 7 public: 8 complex(){ real = imag = 0;} 9 complex(double r, double i) 10 { 11 real = r; 12 imag = i; 13 } 14 complex operator + (const complex &c); 15 complex operator - (const complex &c); 16 complex operator * (const complex &c); 17 complex operator / (const complex &c); 18 19 friend void print(const complex &c); //友元函数 20 21 private: 22 double real; //实部 23 double imag; //虚部 24 25 }; 26 27 inline complex complex::operator + (const complex &c) //定义为内联函数,代码复制,运算效率高 28 { 29 return complex(real + c.real, imag + c.imag); 30 } 31 32 inline complex complex::operator - (const complex &c) 33 { 34 return complex(real - c.real, imag - c.imag); 35 } 36 37 inline complex complex::operator * (const complex &c) 38 { 39 return complex(real * c.real - imag * c.imag, real * c.real + imag * c.imag); 40 } 41 42 inline complex complex::operator / (const complex &c) 43 { 44 return complex( (real * c.real + imag * c. imag) / (c.real * c.real + c.imag * c.imag), 45 (imag * c.real - real * c.imag) / (c.real * c.real + c.imag * c.imag) ); 46 } 47 48 void print(const complex &c) 49 { 50 if(c.imag < 0) 51 cout<<c.real<<c.imag<<'i'<<endl; 52 else 53 cout<<c.real<<'+'<<c.imag<<'i'<<endl; 54 } 55 56 int main() 57 { 58 complex c1(2.0, 3.5), c2(6.7, 9.8), c3; 59 c3 = c1 + c2; 60 cout<<"c1 + c2 = "; 61 print(c3); //友元函数不是成员函数,只能采用普通函数调用方式,不能通过类的对象调用 62 63 c3 = c1 - c2; 64 cout<<"c1 - c2 = "; 65 print(c3); 66 67 c3 = c1 * c2; 68 cout<<"c1 * c2 = "; 69 print(c3); 70 71 c3 = c1 / c2; 72 cout<<"c1 / c2 = "; 73 print(c3); 74 return 0; 75 }
三、程序运行结果