函数重载就是对一个已有的函数赋予新的含义实现不同功能,即一名多用
运算符也可以重载。其实计算机处理整数、单精度数、双精度数加法的操作方法不同,由于c++对运算符“+”进行重载,使“+”适用于int,float,double类型的不同运算。
运算符重载的方法是定义一个重载运算符的函数,实质就是函数的重载。函数一般格式:
函数类型 operator 运算符名(形参表)
{对运算符的重载处理}
注意:函数名由operator和运算符组成)如,int operator + (int a,int b){return (a+b);}
例如,对“+”实行重载,使之能用于两复数相加
#include <iostream> using namespace std; class Complex {public: Complex( ){real=0;imag=0;} //无参构造函数 Complex(double r,double i){real=r;imag=i;}//带参构造函数 Complex operator+(Complex &c2);//声明重载运算符的函数 void display( ); private: double real; double imag; }; Complex Complex∷operator+(Complex &c2) //定义重载运算符的函数 { Complex c; c.real=real+c2.real; c.imag=imag+c2.imag; return c;} void Complex∷display( ) { cout<<″(″<<real<<″,″<<imag<<″i)″<<endl;} int main( ) { Complex c1(3,4),c2(5,-10),c3; c3=c1+c2; //运算符+用于复数运算 cout<<″c1=″;c1.display( ); cout<<″c2=″;c2.display( ); cout<<″c1+c2=″;c3.display( ); return 0; }
注意点:
运算符被重载后,其原有的功能仍然保留,没有丧失或改变
通过运算符重载,扩大了 C++已有运算符的作用范围,使之能用于类对象。
运算符重载对 C++有重要的意义,把运算符重载和类结合起来,可以在 C++程序中定义出很有实用意义而使用方便的新的数据类型。
运算符重载使 C++具有更强大的功能、 更好的可扩充性和适应性,这是 C++最吸引人的特点之一。
(1) C++不允许用户自己定义新的运算符,只能对已有的 C++运算符进行重载。
(2) C++允许重载的运算符
C++中绝大部分的运算符允许重载 ,不能重载的运算符只有 5 个:
. (成员访问运算符)
.* (成员指针访问运算符)
∷ (域运算符)
sizeof(长度运算符)
?: (条件运算符)
前两个运算符不能重载是为了保证访问成员的功能不能被改变,域运算符和sizeof 运算符的运算对象是类型而不是变量或一般表达式,不具重载的特征。
(3) 重载不能改变运算符运算对象(即操作数)的个数。
(4) 重载不能改变运算符的优先级别。
(5) 重载不能改变运算符的结合性。
(6) 重载运算符的函数不能有默认的参数,否则就改变了运算符参数的个数,与前面第(3)点矛盾。
(7) 重载的运算符必须和用户定义的自定义类型的对象一起使用,其参数至少应有一个是类对象(或类对象的引用)。 也就是说,参数不能全部是 C++的标准类型,以防止用户修改用于标准类型数据的运算符的性质。
(8) 用于类对象的运算符一般必须重载,但有两个例外,运算符“=”和“&”不必用户重载。
① 赋值运算符(=)可以用于每一个类对象,可以利用它在同类对象之间相互赋值。
② 地址运算符&也不必重载,它能返回类对象在内存中的起始地址。
(9) 应当使重载运算符的功能类似于该运算符作用于标准类型数据时所实现的功能。
(10) 运算符重载函数可以是类的成员函数,也可以是类的友元函数,还可以是既非类的成员函数也不是友元函数的普通函数。
例如,将上面重载函数不作为成员函数,而放在类外,作为 Complex 类的友元函数
#include <iostream> using namespace std; 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 display( ); private: double real; double imag; }; Complex operator + (Complex &c1,Complex &c2) //定义作为友元函数的重载函数 {return Complex(c1.real+c2.real, c1.imag+c2.imag);} void Complex∷display( ) {cout<<″(″<<real<<″,″<<imag<<″i)″<<endl;} int main( ) {Complex c1(3,4),c2(5,-10),c3; c3=c1+c2; cout<<″c1=″; c1.display( ); cout<<″c2=″; c2.display( ); cout<<″c1+c2 =″; c3.display( ); }
解决运算符重载后使用交换律:
//转换构造函数:(将一个其他类型(肯定包括类类型了)的数据转换成一个类的对象p.332)
转换构造函数只能有一个参数,Complex(double r){real=r;imag=0;}
现在可以Complex c=c1+(Complex)2.3
//类型转换函数:同上反,将一个类的对象转换成另一个类型的数据)
在函数名前不能指定函数类型,没有参数:operator double(){return real;}
现在可以double d=2.3+c1;
一个包含转换构造函数,类型转换函数,重载运算符+ 的友元函数的例子
#include <iostream> using namespace std; class Complex {public: Complex(){real=0;imag=0;} Complex(double r){real=r;imag=0;} //转换构造函数 Complex(double r,double i){real=r;imag=i;} operator double(){return real;} //类型转换函数 friend Complex operator+(Complex c1,Complex c2);//重载运算符+ 的友元函数 void display(); private: double real; double imag; }; Complex operator +(Complex c1,Complex c2) { return Complex(c1.real+c2.real,c1.imag+c2.imag);} void Complex::display() {cout<<"("<<real<<", "<<imag<<")"<<endl;} int main() {Complex c1(3,4),c2; double d1; d1=2.5+c1; cout<<"d1="<<d1<<endl; c2=Complex(d1); cout<<"c2="; c2.display(); return 0; }