数据结构运算符重载幻灯片.ppt
数据结构运算符重载数据结构运算符重载第1页,共75页,编辑于2022年,星期六10.1 什么是运算符重载什么是运算符重载lC+中预定义的运算符的操作对象只能是基本中预定义的运算符的操作对象只能是基本数据类型。但实际上,对于许多用户自定义数据类型。但实际上,对于许多用户自定义的类型,也需要类似的运算。这时就必须重的类型,也需要类似的运算。这时就必须重新定义这些运算符,赋于已有运算符新的功新定义这些运算符,赋于已有运算符新的功能,使之能够用于特定类型执行特定操作。能,使之能够用于特定类型执行特定操作。第2页,共75页,编辑于2022年,星期六l实际上,很多实际上,很多C+操作符已经被重载。例如,操作符已经被重载。例如,将将*操作符用于地址,将得到在这个地址中的操作符用于地址,将得到在这个地址中的值;但将它用于两个数字时,得到的将是它值;但将它用于两个数字时,得到的将是它们的乘积。们的乘积。lC+根据操作数的数目和类型来决定采用哪种根据操作数的数目和类型来决定采用哪种操作。操作。第3页,共75页,编辑于2022年,星期六l使同一个运算符作用于不同类型的数据时导使同一个运算符作用于不同类型的数据时导致不同的行为的这种机制称为致不同的行为的这种机制称为运算符重载运算符重载。lC+通过重载运算符使之用于通过重载运算符使之用于自定义类型自定义类型,扩,扩展了运算符的功能,这也是展了运算符的功能,这也是C+最具吸引力的最具吸引力的优点之一。优点之一。第4页,共75页,编辑于2022年,星期六运算符重载机制运算符重载机制l运算符重载是通过重载一种特殊函数运算符重载是通过重载一种特殊函数运算符函数来运算符函数来实现的。实现的。l对对C+运算符可作如下理解:运算符可作如下理解:l编译器在对运算符进行编译处理时,将一个运算符编译成如编译器在对运算符进行编译处理时,将一个运算符编译成如下形式:下形式:l一元运算符:一元运算符:obj operator(obj)l二元运算符:二元运算符:obj1obj2 operator(obj1,obj2)l由于由于C+中有前增(减)、后增(减),为了区分它中有前增(减)、后增(减),为了区分它们,们,C+将后增(减)编译成:将后增(减)编译成:l后增:后增:obj+operator+(obj,0)l后减:后减:obj-operator-(obj,0)第5页,共75页,编辑于2022年,星期六l依照上述规则,依照上述规则,8+9、10.5+3.5分别编译成运分别编译成运算符函数调用形式为:算符函数调用形式为:loperator+(8,9);loperator+(10.5,3.5);lC+为为+运算符提供了多种运算符函数,其原运算符提供了多种运算符函数,其原型有:型有:loperator+(int,int);loperator+(double,double);l等等第6页,共75页,编辑于2022年,星期六10.2 运算符重载的方法运算符重载的方法l运算符重载的方法是定义一个重载运算符的运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算。也就自动调用该函数,以实现相应的运算。也就是说,运算符重载是通过定义函数实现的。就是说,运算符重载是通过定义函数实现的。l l运算符重载实质上是函数的重载。运算符重载实质上是函数的重载。第7页,共75页,编辑于2022年,星期六l重载运算符的函数一般格式如下:重载运算符的函数一般格式如下:l函数类型函数类型 operator 运算符名称运算符名称(形参表列形参表列)l l 对运算符的重载处理对运算符的重载处理 l第8页,共75页,编辑于2022年,星期六#include using namespace std;class Complex double real;double imag;public:Complex()real=0;imag=0;Complex(double r,double i):real(r),imag(i)friend friend Complex operator+(Complex&c1,Complex&c2);void display();第9页,共75页,编辑于2022年,星期六Complex operator+(Complex&c1,Complex&c2)Complex c;c.real=c1.real+c2.real;c.imag=c1.imag+c2.imag;return c;void Complex:display()cout(real,imagi)endl;第10页,共75页,编辑于2022年,星期六int main()Complex c1(3,4),c2(5,-10),c3;c3=c1+c2;coutc1=;c1.display();coutc2=;c2.display();cout、=运算符,运算符运算符,运算符重载函数重载函数必须必须为类的成员函数。为类的成员函数。为什么?为什么?第22页,共75页,编辑于2022年,星期六10.5 重载双目运算符重载双目运算符l双目运算符双目运算符(或称二元运算符或称二元运算符)是是C+中最常用中最常用的运算符。双目运算符有两个操作数,通常的运算符。双目运算符有两个操作数,通常在运算符的左右两侧,如在运算符的左右两侧,如3+5,a=b,i10等。等。在重载双目运算符时,不言而喻在函数中应在重载双目运算符时,不言而喻在函数中应该有两个参数。下面再举一个例子说明重载该有两个参数。下面再举一个例子说明重载双目运算符的应用。双目运算符的应用。第23页,共75页,编辑于2022年,星期六例例l定义一个字符串类定义一个字符串类String,用来存放不定长的,用来存放不定长的字符串,重载运算符字符串,重载运算符“=”,“”,用于两个字符串的等于、小于和大于的比较用于两个字符串的等于、小于和大于的比较运算。运算。l下面分几步来介绍编程过程。下面分几步来介绍编程过程。第24页,共75页,编辑于2022年,星期六 先建立一个先建立一个String类类l#include lusing namespace std;lclass Stringllpublic:l String()l l p=NULL;/默认构造函数默认构造函数l l String(char*str);/构造函数构造函数l void display();lprivate:l char*p;/字符型指针,用于指向字符串字符型指针,用于指向字符串l;第25页,共75页,编辑于2022年,星期六lString:String(char*str)/定义构造函数定义构造函数ll p=str;/使使p指向实参字符串指向实参字符串llvoid String:display()/输出输出p所指向的字符串所指向的字符串ll coutp;l第26页,共75页,编辑于2022年,星期六lint main()ll String string1(Hello),string2(Book);l string1.display();l cout”。l#include l#include lusing namespace std;lclass Stringllpublic:l String()l l p=NULL;/默认构造函数默认构造函数l l String(char*str);/构造函数构造函数l void display();l friend bool operator(String&string1,String&string2);lprivate:l char*p;/字符型指针,用于指向字符串字符型指针,用于指向字符串l;第28页,共75页,编辑于2022年,星期六lString:String(char*str)/定义构造函数定义构造函数ll p=str;/使使p指向实参字符串指向实参字符串llvoid String:display()/输出输出p所指向的字符串所指向的字符串ll cout(String&string1,String&string2)ll if(strcmp(string1.p,string2.p)0)l return true;l else return false;l第29页,共75页,编辑于2022年,星期六lint main()ll String string1(Hello),string2(Book);l coutstring2)endl;ll程序运行结果为程序运行结果为1。l其他两个运算符的重载如法炮制即可。其他两个运算符的重载如法炮制即可。第30页,共75页,编辑于2022年,星期六 扩展到对扩展到对3个运算符重载。个运算符重载。l见教材见教材P325l通过这个例子,不仅可以学习到有关双目运算符重载的知通过这个例子,不仅可以学习到有关双目运算符重载的知识,而且还可以学习怎样去编写识,而且还可以学习怎样去编写C+程序。程序。l这种方法的指导思想是:这种方法的指导思想是:先搭框架,逐步扩充,由简到先搭框架,逐步扩充,由简到繁,最后完善。繁,最后完善。l边编程,边调试,边扩充。千万不要企图在一开始时就解决边编程,边调试,边扩充。千万不要企图在一开始时就解决所有的细节。类是可扩充的,可以一步一步地扩充它的功能。所有的细节。类是可扩充的,可以一步一步地扩充它的功能。最好直接在计算机上写程序,每一步都要上机调试,调试通最好直接在计算机上写程序,每一步都要上机调试,调试通过了前面一步再做下一步,步步为营。过了前面一步再做下一步,步步为营。第31页,共75页,编辑于2022年,星期六10.6 重载单目运算符重载单目运算符l单目运算符只有一个操作数,如单目运算符只有一个操作数,如!a,-b,&c,*p,还有最常用的,还有最常用的+i和和-i等。重载单目运等。重载单目运算符的方法与重载双目运算符的方法是类似算符的方法与重载双目运算符的方法是类似的。但由于单目运算符只有一个操作数,因的。但由于单目运算符只有一个操作数,因此运算符重载函数只有一个参数。此运算符重载函数只有一个参数。l单目运算符一般重载为成员函数。单目运算符一般重载为成员函数。第32页,共75页,编辑于2022年,星期六例例l有一个有一个Time类,包含数据成员类,包含数据成员minute(分分)和和sec(秒秒),模拟秒表,每次走一秒,满,模拟秒表,每次走一秒,满60秒进秒进一分钟,此时秒又从一分钟,此时秒又从0开始算。要求输出分和开始算。要求输出分和秒的值。秒的值。第33页,共75页,编辑于2022年,星期六l#include lusing namespace std;lclass Timellpublic:l Time()l l minute=0;/默认构造函数默认构造函数l sec=0;l l Time(int m,int s):minute(m),sec(s)/构造函数重载构造函数重载l Time operator+();/声明运算符重载函数声明运算符重载函数l void display()l l coutminute:sec=60)l l sec-=60;/满满60秒进秒进1分钟分钟l +minute;l l return*this;/返回当前对象值返回当前对象值l第35页,共75页,编辑于2022年,星期六lint main()ll Time time1(34,0);l for(int i=0;i61;i+)l l +time1;l time1.display();l l return 0;l第36页,共75页,编辑于2022年,星期六l“+”和和“-”运算符有两种使用方式,前运算符有两种使用方式,前置自增运算符和后置自增运算符,它们的作置自增运算符和后置自增运算符,它们的作用是不一样的,在重载时怎样区别这二者呢用是不一样的,在重载时怎样区别这二者呢?l针对针对“+”和和“-”这一特点,这一特点,C+约定:约定:在自增在自增(自减自减)运算符重载函数中,增加一个运算符重载函数中,增加一个int型形参,就是后置自增型形参,就是后置自增(自减自减)运算符函数。运算符函数。第37页,共75页,编辑于2022年,星期六例例l在上例程序的基础上增加对后置自增运算符在上例程序的基础上增加对后置自增运算符的重载。修改后的程序如下:的重载。修改后的程序如下:第38页,共75页,编辑于2022年,星期六lclass Timellpublic:l Time()l l minute=0;/默认构造函数默认构造函数l sec=0;l l Time(int m,int s):minute(m),sec(s)/构造函数重载构造函数重载l Time operator+();/声明前置自增运算符声明前置自增运算符+重载函数重载函数l Time operator+(int);/声明后置自增运算符声明后置自增运算符+重载函数重载函数l void display()l l coutminute:sec=60)l l sec-=60;l +minute;l l return*this;l第40页,共75页,编辑于2022年,星期六lTime Time:operator+(int)ll Time temp(*this);l sec+;l if(sec=60)l l sec-=60;l +minute;l l return temp;/返回的是自加前的对象返回的是自加前的对象l可以看到:可以看到:可以看到:可以看到:重载后置自增运算符时,多了一个重载后置自增运算符时,多了一个重载后置自增运算符时,多了一个重载后置自增运算符时,多了一个intint型的参数,增加这个型的参数,增加这个型的参数,增加这个型的参数,增加这个参数只是为了与前置自增运算符重载函数有所区别,此外没有任何作参数只是为了与前置自增运算符重载函数有所区别,此外没有任何作参数只是为了与前置自增运算符重载函数有所区别,此外没有任何作参数只是为了与前置自增运算符重载函数有所区别,此外没有任何作用。编译系统在遇到重载后置自增运算符时,会自动调用此函数。用。编译系统在遇到重载后置自增运算符时,会自动调用此函数。用。编译系统在遇到重载后置自增运算符时,会自动调用此函数。用。编译系统在遇到重载后置自增运算符时,会自动调用此函数。第41页,共75页,编辑于2022年,星期六lint main()ll Time time1(34,59),time2;l couttime1:;l time1.display();l +time1;l cout+time1:;l time1.display();l time2=time1+;l couttime1+:;l time1.display();l couttime2:;l time2.display();第42页,共75页,编辑于2022年,星期六10.7 重载流插入运算符和流提取运算符重载流插入运算符和流提取运算符lC+的流插入运算符的流插入运算符“”是是C+在类库中提供的,所有在类库中提供的,所有C+编译系统都在类库中提供输入编译系统都在类库中提供输入流类流类istream和输出流类和输出流类ostream。lcin和和cout分别是分别是istream类和类和ostream类的对象。在类的对象。在类库提供的头文件中已经对类库提供的头文件中已经对“”进行了重进行了重载,使之作为流插入运算符和流提取运算符,能用来载,使之作为流插入运算符和流提取运算符,能用来输出和输入输出和输入C+标准类型标准类型的数据。因此,凡是用的数据。因此,凡是用“cout”对标准类型数据进行输入输出对标准类型数据进行输入输出的,都要用的,都要用#include 把头文件包含到本把头文件包含到本程序文件中。程序文件中。第43页,共75页,编辑于2022年,星期六l用户自己定义类型用户自己定义类型的数据,是不能直接用的数据,是不能直接用“”来输出和输入的。如果想用它们输出和输入自己声来输出和输入的。如果想用它们输出和输入自己声明的类型的数据,必须对它们重载。明的类型的数据,必须对它们重载。l对对“”重载的函数形式如下:重载的函数形式如下:listream&operator (istream&,自定义类自定义类&);lostream&operator”的函数的第一个参数和函数的类型的函数的第一个参数和函数的类型都都必须必须是是istream&类型,第二个参数是要进行输入操类型,第二个参数是要进行输入操作的类。重载作的类。重载“”和和“”的函数作的函数作为友元函数或普通的函数,而不能将它们定义为成员为友元函数或普通的函数,而不能将它们定义为成员函数。函数。第44页,共75页,编辑于2022年,星期六10.7.1 重载流插入运算符重载流插入运算符“”l例例 用重载的用重载的“”输出复数。输出复数。第45页,共75页,编辑于2022年,星期六lclass Complexllpublic:l Complex()l l real=0;l imag=0;l l Complex(double r,double i)l l real=r;l imag=i;l l Complex operator+(Complex&c2);l friend ostream&operator (ostream&,Complex&);lprivate:l double real;l double imag;l;第46页,共75页,编辑于2022年,星期六lComplex Complex:operator+(Complex&c2)ll return Complex(real+c2.real,imag+c2.imag);llostream&operator (ostream&output,Complex&c)ll output(c.real+c.imagi)endl;l return output;l请思考:请思考:请思考:请思考:return outputreturn output的作用是什么的作用是什么的作用是什么的作用是什么?第47页,共75页,编辑于2022年,星期六int main()Complex c1(2,4),c2(6,10),c3;c3=c1+c2;cout”lC+预定义的运算符预定义的运算符“”的作用是从一个输的作用是从一个输入流中提取数据,如入流中提取数据,如“cini;”表示从输入表示从输入流中提取一个整数赋给变量流中提取一个整数赋给变量i(假设已定义假设已定义i为为int型型)。重载流提取运算符的目的是希望将。重载流提取运算符的目的是希望将“”用于输入自定义类型的对象的信息。用于输入自定义类型的对象的信息。第49页,共75页,编辑于2022年,星期六lclass Complexllpublic:l Complex()l l real=0;l imag=0;l l Complex(double r,double i)l l real=r;l imag=i;l l Complex operator+(Complex&c2);l friend ostream&operator (istream&,Complex&);lprivate:l double real;l double imag;l;第50页,共75页,编辑于2022年,星期六lComplex Complex:operator+(Complex&c2)ll return Complex(real+c2.real,imag+c2.imag);llostream&operator (ostream&output,Complex&c)ll output(c.real+c.imagi)(istream&input,Complex&c)coutc.real;coutc.imag;return input;第52页,共75页,编辑于2022年,星期六lint main()ll Complex c1,c2;l cinc1c2;l coutc1=c1endl;l coutc2=c2endl;l return 0;l第53页,共75页,编辑于2022年,星期六10.8 不同类型数据间的转换不同类型数据间的转换10.8.1 标准类型数据间的转换标准类型数据间的转换l在在C+中,某些不同类型数据之间可以自动转换,例如中,某些不同类型数据之间可以自动转换,例如lint i=6;li=7.5+i;l编译系统对编译系统对 7.5是作为是作为double型数处理的,在求解表型数处理的,在求解表达式时,先将达式时,先将6转换成转换成double型,然后与型,然后与7.5相加,得相加,得到和为到和为13.5,在向整型变量,在向整型变量i赋值时,将赋值时,将13.5转换为整转换为整数数13,然后赋给,然后赋给i。这种转换是由。这种转换是由C+编译系统自动完编译系统自动完成的,用户不需干预。这种转换称为隐式类型转换。成的,用户不需干预。这种转换称为隐式类型转换。第54页,共75页,编辑于2022年,星期六lC+还提供显式类型转换,程序人员在程序中指定将一种指还提供显式类型转换,程序人员在程序中指定将一种指定的数据转换成另一指定的类型,其形式为定的数据转换成另一指定的类型,其形式为 l类型名类型名(数据数据)l如如lint(89.5)l其作用是将其作用是将89.5转换为整型数转换为整型数89。l对于用户自己声明的类型,编译系统并不知道怎样进对于用户自己声明的类型,编译系统并不知道怎样进行转换。行转换。解决这个问题的关键是让编译系统知道怎样解决这个问题的关键是让编译系统知道怎样去进行这些转换,需要定义专门的函数来处理。去进行这些转换,需要定义专门的函数来处理。第55页,共75页,编辑于2022年,星期六10.8.2 转换构造函数转换构造函数l l转换构造函数转换构造函数转换构造函数转换构造函数的作用是将一个其他类型的数据转换成一个类的对象。的作用是将一个其他类型的数据转换成一个类的对象。l先回顾一下以前学习过的几种构造函数:先回顾一下以前学习过的几种构造函数:l默认构造函数。以默认构造函数。以Complex类为例,函数原型的形式为类为例,函数原型的形式为 Complex();/没有参数没有参数l用于初始化的构造函数。函数原型的形式为用于初始化的构造函数。函数原型的形式为 Complex(double r,double i);/形参表列中一般有两个以上形参表列中一般有两个以上参数参数l用于复制对象的复制构造函数。函数原型的形式为用于复制对象的复制构造函数。函数原型的形式为 Complex(Complex&c);/形参是本类对象的引用形参是本类对象的引用第56页,共75页,编辑于2022年,星期六l现在又要介绍一种新的构造函数现在又要介绍一种新的构造函数转换构转换构造函数。造函数。l转换构造函数只有一个形参,如转换构造函数只有一个形参,如 lComplex(double r)real=r;imag=0;l其作用是将其作用是将double型的参数型的参数r转换成转换成Complex类的对象,将类的对象,将r作为复数的实部,虚部为作为复数的实部,虚部为0。用户可以根据需要定义转换构造函数,在函用户可以根据需要定义转换构造函数,在函数体中告诉编译系统怎样去进行转换。数体中告诉编译系统怎样去进行转换。第57页,共75页,编辑于2022年,星期六l在类体中,可以有转换构造函数,也可以没在类体中,可以有转换构造函数,也可以没有转换构造函数,视需要而定。以上几种构有转换构造函数,视需要而定。以上几种构造函数可以同时出现在同一个类中,它们是造函数可以同时出现在同一个类中,它们是构造函数的重载。编译系统会根据建立对象构造函数的重载。编译系统会根据建立对象时给出的实参的个数与类型选择形参与之匹时给出的实参的个数与类型选择形参与之匹配的构造函数。配的构造函数。第58页,共75页,编辑于2022年,星期六l使用转换构造函数将一个指定的数据转换为类对象的使用转换构造函数将一个指定的数据转换为类对象的方法如下:方法如下:l(1)先声明一个类。先声明一个类。l(2)在这个类中定义一个只有一个参数的构造函数,在这个类中定义一个只有一个参数的构造函数,参数的类型是需要转换的类型,在函数体中指定转换的参数的类型是需要转换的类型,在函数体中指定转换的方法。方法。l(3)在该类的作用域内可以用以下形式进行类型转换:在该类的作用域内可以用以下形式进行类型转换:类名类名(指定类型的数据指定类型的数据)l就可以将指定类型的数据转换为此类的对象。就可以将指定类型的数据转换为此类的对象。第59页,共75页,编辑于2022年,星期六class Complexpublic:Complex():real(0),imag(0)Complex(double r,double i):real(r),imag(i)Complex(double r):real(r),imag(0)Complex operator+(Complex c2);friend ostream&operator (ostream&,Complex&);private:double real;double imag;第60页,共75页,编辑于2022年,星期六Complex Complex:operator+(Complex c2)return Complex(real+c2.real,imag+c2.imag);ostream&operator (ostream&output,Complex&c)output(c.real+c.imagi)endl;return output;第61页,共75页,编辑于2022年,星期六lint main()ll Complex c1(3,6),c2;l c2=c1+(Complex)8.2;l /c2=c1+Comples(8.2);l /c2=c1+8;l /c2=8+c1;l coutc2endl;l return 0;l第62页,共75页,编辑于2022年,星期六lclass Complexllpublic:l Complex():real(0),imag(0)l Complex(double r,double i):real(r),imag(i)l Complex(double r):real(r),imag(0);l friend Complex operator+(Complex c1,Complex c2);l friend ostream&operator (ostream&,Complex&);lprivate:l double real;l double imag;l;第63页,共75页,编辑于2022年,星期六lComplex operator+(Complex c1,Complex c2)ll return Complex(c1.real+c2.real,c1.imag+c2.imag);llostream&operator (ostream&output,Complex&c)ll output(c.real+c.imagi)endl;l return output;l第64页,共75页,编辑于2022年,星期六lint main()ll Complex c1(3,6),c2;l c2=8+c1;/okl coutc2endl;l return 0;l对称运算符一般重载为友元函数。对称运算符一般重载为友元函数。第65页,共75页,编辑于2022年,星期六10.8.3 类型转换函数类型转换函数l用转换构造函数可以将一个指定类型的数据用转换构造函数可以将一个指定类型的数据转换为类的对象。但是不能反过来将一个类转换为类的对象。但是不能反过来将一个类的对象转换为一个其他类型的数据的对象转换为一个其他类型的数据(例如将一例如将一个个Complex类对象转换成类对象转换成double类型数据类型数据)。第66页,共75页,编辑于2022年,星期六lC+提供类型转换函数提供类型转换函数(type conversion function)来解来解决这个问题。类型转换函数的作用是将一个类的对象转换决这个问题。类型转换函数的作用是将一个类的对象转换成另一类型的数据。成另一类型的数据。l类型转换函数的一般形式为类型转换函数的一般形式为 loperator 类型名类型名()ll 实现转换的语句实现转换的语句ll在函数名前面在函数名前面不能指定函数类型不能指定函数类型,函数,函数没有参数没有参数。其返回。其返回值的类型是由值的类型是由函数名函数名中指定的类型名来确定的。类型转换中指定的类型名来确定的。类型转换函数函数只能作为成员函数只能作为成员函数,因为转换的主体是本类的对象。,因为转换的主体是本类的对象。第67页,共75页,编辑于2022年,星期六l如果已声明了一个如果已声明了一个Complex类,可以在类,可以在Complex类中这类中这样定义类型转换函数:样定义类型转换函数:operator double()return real;ldouble类型经过重载后,除了原有的含义外,还获得类型经过重载后,除了原有的含义外,还获得新的含义新的含义(将一个将一个Complex类对象转换为类对象转换为double类型类型数据,并指定了转换方法数据,并指定了转换方法)。这样,编译系统不仅能识。这样,编译系统不仅能识别原有的别原有的double型数据,而且还会把型数据,而且还会把Complex类对象类对象作为作为double型数据处理。型数据处理。第68页,共75页,编辑于2022年,星期六l那么程序中的那么程序中的Complex类对具有双重身份,类对具有双重身份,既是既是Complex类对象,又可作为类对象,又可作为double类型类型数据。数据。Complex类对象只有在需要时才进行类对象只有在需要时才进行转换,要根据表达式的上下文来决定。转换,要根据表达式的上下文来决定。l转换构造函数和类型转换运算符有一个共同转换构造函数和类型转换运算符有一个共同的功能:的功能:当需要的时候,编译系统会自动调当需要的时候,编译系统会自动调用这些函数,建立一个无名的临时对象用这些函数,建立一个无名的临时对象(或临或临时变量时变量)。第69页,共75页,编辑于2022年,星期六lclass Complexllpublic:l Complex():real(0),imag(0)l Complex(double r,double i):real(r),imag(i)l Complex operator+(Complex c2);l operator double()l l return real;l l friend ostream&operator (ostream&,Complex&);lprivate:l double real;l double imag;l;第70页,共75页,编辑于2022年,星期六lComplex Complex:operator+(Complex c2)ll return Complex(real+c2.real,imag+c2.imag);llostream&operator (ostream&output,Complex&c)ll output(c.real+c.imagi)endl;l return output;l第71页,共75页,编辑于2022年,星期六lint main()ll Complex c1(3,4),c2(5,-10),c3;l double d;l d=2.5+c1;l coutdendl;l return 0;l第72页,共75页,编辑于2022年,星期六包含转换构造函数、运算符重载函数和类型转换函数的程序包含转换构造函数、运算符重载函数和类型转换函数的程序lclass Complexllpublic:l Complex():real(0),imag(0)l Complex(double r,double i):real(r),imag(i)l Complex(double r):real(r),imag(0);l operator double()l l return real;l l friend Complex operator+(Complex c1,Complex c2);l friend ostream&operator (ostream&,Complex&);lprivate:l double real;l double imag;l;第73页,共75页,编辑于2022年,星期六lComplex operator+(Complex c1,Complex c2)ll return Complex(c1.real+c2.real,c1.imag+c2.imag);llostream&operator (ostream&output,Complex&c)ll output(c.real+c.imagi)endl;l return output;l第74页,共75页,编辑于2022年,星期六lint main()ll Complex c1(3,6),c2;l c2=Complex(8)+c1;/okl /c2=8+c1;出现二义性。出现二义性。l coutc2endl;l return 0;l第75页,共75页,编辑于2022年,星期六