收藏 分销(赏)

第四章 运算符重载.ppt

上传人:pc****0 文档编号:13180028 上传时间:2026-01-30 格式:PPT 页数:81 大小:455.50KB 下载积分:10 金币
下载 相关 举报
第四章 运算符重载.ppt_第1页
第1页 / 共81页
第四章 运算符重载.ppt_第2页
第2页 / 共81页


点击查看更多>>
资源描述
单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,单击此处编辑母版标题样式,第四章 运算符重载,4.1,什么是运算符重载,4.2,运算符重载的方法,4.3,重载运算符的规则,4.4,运算符重载函数作为类成员函数和友元函数,4.5,重载双目运算符,4.6,重载单目运算符,4.7,重载流插入运算符和流提取运算符,4.8,不同类型数据间的转换,4.1,什么是运算符重载,C+,为程序员提供了灵活的手段,让程序员自己定义类,自己设计相应的运算符(必须在已有的运算符基础上设计),使之应用于自己定义的类。与函数重载类似,对已有的运算符赋予新的含义,,用一个运算符表示不同功能的运算,这就是运算符重载,。,实际上,我们在此之前已经使用了运算符重载。如,是,C+,的移位运算符,它又与流对象,cout,配合作为流插入运算符,这是,C+,对,进行了重载处理。,运算符重载的实质,运算符重载是对已有的运算符赋予多重含义。,必要性,C+,中预定义的运算符其运算对象只能是基本数据类型,而不适用于用户自定义类型(如类),实现机制,将指定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参。,编译系统对重载运算符的选择,遵循函数重载的选择原则。,例,4.1,通过成员函数实现复数的加法。,class Complex,private:,double real;,double,imag,;,public:,Complex()real,=0;imag=0;,Complex(double,r,double,i)real,=,r;imag,=i;,Complex,complex_add(Complex,void display();,;,Complex,Complex:complex_add(Complex,&c2),Complex c;,c.real,=real+c2.real;,c.imag,=imag+c2.image;,return c;,void,Complex:display,(),cout,(real,imag,i),endl,;,int,main(),Complex c1(3,4),c2(5,-10),c3;,c3=plex_add(c2);,cout,c1=;c1.display();,cout,c2=;c2.display();,cout,real+c2.real;,c.imag,=this-imag+c2.imag;,在,main,函数中通过对象,c1,调用加法函数,上面的语句相当于:,c.real,=c1.real+c2.real;,c.imag,=c1.imag+c2.imag;,能否用,+,运算符实现复数加法?,4.2,运算符重载的方法,运算符重载的方法是定义一个重载运算符函数,在需要时系统自动调用该函数,完成相应的运算。运算符重载实质上是函数的重载。运算符重载函数的格式是:,数据类型,operator,运算符,(,形参表,),重载处理,数据类型:是重载函数值的数据类型。,operator,是保留字,规则和限制,C+,中可以重载除下列运算符外的所有运算符:,.*:?:,sizeof,(),只能重载,C+,语言中已有的运算符,不可臆造新的。,不改变原运算符的优先级和结合性。,不能改变操作数个数。,经重载的运算符,其操作数中至少应该有一个是自定义类型。,两种形式,重载为类成员函数。,重载为友元函数。,运算符函数,声明形式,函数类型,operator,运算符(形参),.,重载为类成员函数时,参数个数,=,原操作数个数,-1,(后置,+,、,-,除外),重载为友元函数时,参数个数,=,原操作数个数,,且至少应该有一个自定义类型的形参。,不能重载的运算符只有,5,个:,.,成员运算符,.*,成员指针运算符,:,域运算符,sizeof,长度运算符,?:,条件运算符,重载函数名是由,operator,和运算符联合组成。,复数加法运算符重载函数原型可以是:,Complex operator+(Complex,例,4.2,重载运算符,+,,用于两个复数相加。,分析:定义一个复数类,用成员函数实现加号的重载函数。两个复数相加结果仍是复数,所以函数的返回值的类型也是复数类。用成员函数实现运算符重载函数时,调用格式是,“对象名,.,成员名”,,此时对象就是一个参与运算的操作数,加法还需要另一个操作数,这个操作数用函数的参数传递,参数的类型就是复数类。而运算结果用函数值返回。,class Complex,public:,Complex()real,=0;imag=0;,Complex(double,r,double,i)real,=,r;imag,=i;,Complex,operator+,(Complex,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;,说明:,(,1,)用运算符重载函数取代了例,4.1,中的加法成员函数,从外观上看函数体和函数返回值都是相同的。,(,2,)在主函数中的表达式,c3=c2+c1,取代了例,4.1,中的,c3=plex_add(c2),,编译系统将表达式,c3=c1+c2,解释为,c1.,operator+,(c2),对象,c1,调用的重载函数,operator+,,以,c2,为实参计算两个复数之和。,请考虑在例,4.2,中能否用一个常量和一个复数相加?如,c3=3+c2;,/,错误,应该定义对象:,Complex C1(3.0,0),:,c3=,C1,+c2;,注意:运算符重载后,其原来的功能仍然保留,编译系统根据运算表达式的上下文决定是否调用运算符重载函数。,运算符重载和类结合起来,可以在,C+,中定义使用方便的新数据类型。,4.3,重载运算符的规则,(,1,),C+,只允许已有的部分运算符实施重载。,(,2,)不能重载的运算符有五个。,(,3,)重载不改变操作数的个数。,(,4,)重载不改变运算符的优先级。,(,5,)运算符重载函数不能带默认值参数。,(,6,)运算符重载函数必须与自定义类型的对象联合使用,其参数至少有一个类对象或类对象引用。,(,7,),C+,默认提供,=,和,&,运算符重载。,(,8,)运算符重载函数可以是类成员函数也可以是类的友元函数,还可以是普通函数。,(,9,),C+,规定赋值运算符、下标运算符、函数调用运算符必须定义为类的成员函数;而输出流插入、输入流提取、类型转换运算符不能定义为类的成员函数。,4.4,运算符重载函数作为类成员函数和友元函数,在例,4.2,程序中对运算符,+,进行了重载,该例将运算符重载函数定义为复数类的成员函数。,从该程序中看到运算符重载为成员函数时,带一个类类型的形参,而另一个加数就是对象自己。,例,4.3,将加法运算符重载为适用于复数加法,重载函数作为类的友元函数。,#include,class Complex,public:,Complex(),real=0;imag=0;,Complex(double r),real=,r;imag,=0;,Complex,(double,r,double,i),real=,r;imag,=i;,friend Complex operator+(Complex,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();,return 0;,加法运算符重载为友元函数,,C+,在编译时将表达式,c1+c2,解释为,operator+(c1,c2),即相当于执行以下函数,Complex operator+(Complex&c1,Complex&c2),return Complex(c1.real+c2.real,c1.imag+c2.imag);,因为普通函数是不能直接访问对象的私有成员,如果普通函数必须访问对象的私有成员,可调用类的公有成员函数访问对象的私有成员。这会降低效率。,书上的错误,如想将一个复数和一个整数相加,运算符重载函数作为成员函数定义如下:,Complex,Complex,:operator+(,int,&i ),return Complex(real+i,imag,);,注意在运算符,+,的左侧必须是,Complex,类对象,程序中可以写成:,c3=c2+n,不能写成:,c3=n+c2,书上的错误,如果要求在使用重载运算符时,运算符左侧操作数不是对象,就不能使用前面定义的运算符重载函数,可以将运算符重载函数定义为友元函数:,friend Complex operator+(,int,&i,Complex&c),return Complex(,c.real,+i,c.imag,);,友元函数不要求第一个参数必须是类类型,但是要求实参要与形参一一对应:,c3=n+c2,/,顺序正确,c3=c2+n,/,顺序错误,为了实现加法的交换率,必须定义两个运算符重载函数,记住成员函数要求运算符左侧的操作数必须是自定义类型的对象,而友元函数没有这个限制,可以用下面两个组合中任意一个:,(,1,)成员函数(左操作数是对象,右操作数是非对象)、友元函数(左操作数是非对象,右操作数是对象),(,2,)友元函数(左操作数是对象,右操作数是非对象)、友元函数(左操作数是非对象,右操作数是对象),由于使用友元会破坏类的封装,要尽量将运算符重载函数定义为成员函数。但考虑到各方面的因素,一般将单目运算符重载为成员函数,将双目运算符重载为友元函数。,VC+6.0,的不带后缀,h,的头文件不支持把成员函数重载为友元函数。,但,VC+6.0,带后缀,h,的头文件支持这项功能,所以要将程序中的语句:,#include,using namespace std;,改成:,#include,即可正常运行。,4.5,重载双目运算符,双目的意思是运算符左边和右边的操作数均参加运算。,如果要重载,B,为类成员函数,使之能够实现表达式,oprd1 B oprd2,,其中,oprd1,为,A,类对象,则,B,应被重载为,A,类的成员函数,形参类型应该是,oprd2,所属的类型。,经重载后,表达式,oprd1 B oprd2,相当于,oprd1.operator B(oprd2),。,例,4.4,定义一个字符串类,String,,用来处理不定长的字符串,重载相等、大于、小于关系运算符,用于两个字符串的等于、大于、小于的比较运算。,操作数,:,两个操作数都是字符串类的对象。,规则,:,两个字符串进行比较。,将,“,”,运算重载为字符串类的成员函数。,(,1,)先建立一个,String,类,#include,#include,class String,/String,是用户自己指定的类名,public:,String()p=NULL;,String(char*,str,);,void display();,private:,char*p;,;,String:String(char,*,str,),p=,str,;,void,String:display,(),cout,p;,int,main(),String string1(Hello),string2(Book);,string1.display();,cout,endl,;,string2.display();,return 0;,先编写出简单的程序框架,编写和调试都比较方便。构造函数是把定义对象时的实参的地址赋予数据成员,p,,,p,是指向实参的指针。程序实现了建立对象、输出字符串对象的功能。程序运行结果分别输出,Hello,Book,(,2,)有了这个基础后,再增加所需的其他内容,先重载大于运算符。程序如下:,/,本程序适用于,VC+6.0,#include,#include,class String,public:,String()p=NULL;,String(char*,str,);,void,display();,friend,bool,operator(String,private:,char*p;,;,String:String(char,*,str,),p=,str,;,void,String:display,(),cout,(String&string1,String&string2),if(strcmp(string1.p,string2.p)0),return true;,else return false;,int,main(),String string1(Hello),string2(Book);,cout,string2),endl,;,return 0;,运算符重载函数定义为友元函数,函数值是布尔类型,在函数中调用了,strcmp,库函数,,string1.p,指向,“,Hello”,,,string2.p,指向,“,Book”,,程序运行结果是,1,。,(,3,)扩展到对三个运算符重载,在,String,类体中声明三个重载函数是友元函数,并编写相应的函数。,/,本程序适用于,VC+6.0,#include,#include,class String,public:,String()p,=NULL;,String(char,*,str,);,friend,bool,operator (String,friend,bool,operator (String,friend,bool,operator=(String,void display();,private:,char*p;,;,String:String(char,*,str,),p=,str,;,void,String:display,(),cout,(String&string1,String&string2),if(strcmp(string1.p,string2.p)0),return true;,else,return false;,bool,operator(String&string1,String&string2),if(strcmp(string1.p,string2.p)0),return true;,else,return false;,bool,operator=(String&string1,String&string2),if(strcmp(string1.p,string2.p)=0),return true;,else,return false;,int,main(),String string1(Hello),string2(Book),string3(Computer);,cout,string2),endl,;,cout,(string1string3),endl,;,cout,(string1=string2),endl,;,return 0;,运行结果为,1,0,0,4.6,重载单目运算符,单目运行符只要一个操作数,由于只有一个操作数,重载函数最多只有一个参数,如果将运算符重载函数定义为成员函数还可以不用参数。,下面以自增运算符,+,为例,学习单目运算符的重载函数的编写方法。,例,4.5,有一个,Time,类,数据成员有时、分、秒。要求模拟秒表,每次走一秒,满,60,秒进位,秒又从零开始计数。满,60,分进位,分又从零开始计数。输出时、分和秒的值。,#include,using namespace std;,class Time,public:,Time()hour,=0;minute=0;sec=0;,Time(int,h,int,m,int,s):hour(h),minute(m),sec(s,),Time operator+();,void,display()cout,hour:minute:sec=60),sec=sec-60;,minute+;,if(minute,=60),minute=minute-60;,hour+;,hour=hour%24;,return*this;,43,int,main(),Time time1(23,59,0);,for(,int,i=0;i61;i+),+time1;,time1.display();,return 0;,C+,中除了有前,+,外,还有后,+,。同样的运算符由于操作数的位置不同,含义也不同。怎样区分前,+,和后,+,?,C+,给了一个方法,在自增或自减运算符重载函数中,增加一个,int,形参。程序员可以选择带,int,形参的函数做后,+,,也可以选择不带,int,形参的函数做前,+,。,例,4.6,在例,4.5,的基础上增加后,+,运算符重载函数。,#include,using namespace std;,class Time,public:,Time()hour,=0;minute=0;sec=0;,Time(int,h,int,m,int,s):hour(h),minute(m),sec(s,),Time operator+();,Time,operator+(int,);,void,display()cout,hour:minute:sec=60),sec=sec-60;,minute+;,if(minute,=60),minute=minute-60;,hour+;,hour=hour%24;,return*this;,47,分析:后,+,运算的含义是操作数先参加其他运算后再自加。如,m=n+,先将,n,的值赋予,m,,然后,n,再自加,1,。设计后,+,重载函数要遵循这个特性。,Time,Time:operator+(int,),Time temp(*this);,/,保存修改前的对象做返回值,+(*this);,return temp;,int,main(),Time time1(21,34,59),time2;,cout,time1:;,time1.display();,+time1;,cout,+time1:;,time1.display();,time2=time1+;,cout,time1+:;,time1.display();,cout,和,移位运算符进行了重载,使它们分别成为流提取运算符和流插入运算符。用来输入或输出,C+,的标准类型数据,所以要用,#include using namespace std;,把头文件包含到程序中。,用户自定义类型的数据不能直接用,输出和输入,如想用它们进行输入或输出,程序员必须对它们重载。,重载函数原型的格式如下:,istream,&operator (,istream,&,自定义类,ostream,&operator,重载函数和,重载函数只能定义为友元函数,不能定义为成员函数,因为函数有两个形参,并且第一个形参不是自定义类型。,4.7.1,重载流插入运算符“,”,例,4.7,在例,4.2,的基础上用,重载函数输出复数。,分析:在类中声明,重载函数是友元函数,friend,ostream,&operator (,ostream&,Complex,在类外定义友元函数:,ostream,&operator (,ostream,&,output,Complex,&c),output(,c.real,+,c.imag,i),endl,;,return output;,/,本程序适用于,VC+6.0,#include,int,main(),Complex c1(2,4),c2(6,10),c3;,c3=c1+c2;,cout,c3;,return 0;,分析,C+,怎样处理,”,cout,c3;”,语句,运算符的左边是,ostream,的对象,cout,,右边是程序员自定义类,complex,的对象,c3,,语句符合运算符重载友元函数,operator,的形参类型要求,系统调用友元函数,,C+,把这个语句解释为:,operator(,cout,c3);,通过形参引用传递,函数中的,output,就是,cout,,函数中的,c,就是,c3,,函数就变成:,cout,(c3.real+c3.imagi),endl,;,return,cout,;,return,cout,是将输出流现状返回。,C+,规定,运算符,”,例,4.8,在例,4.7,的基础上增加流提取运算符,重载函数,用,cin,输入复数,用,cout,(,istream&,Complex,在类外定义函数:,istream,&operator (,istream,&,input,Complex,&c),cout,c.real,c.imag,;,return input;,int main(),Complex c1,c2;,cinc1c2;,coutc1=c1endl;,coutc2=c2,重载函数中的形参,input,是,istream,类对象引用,在执行,cinc1,时,调用,operator,函数,将,cin,引用传递给,input,,,input,是,cin,的别名,同样,c,是,c1,的别名。因此,,input,c.real,c.imag,;,相当于,cin,c1.real c1.imag,。函数返回,cin,的新值。使程序可以用重载函数连续从输入流提取数据给,complex,类对象。,程序逻辑上是正确的,但还有缺陷,如果输入的虚部是负数时,输出的形式变成:,c2=(4+-10i),在负数前多个正号。可以对程序稍做修改:,ostream,&operator (,ostream,&,output,Complex,&c),output(=0)output+;,output,c.imag,i),endl,;,return output;,从本章例子中可以注意到,在运算符重载中使用引用参数的重要性,用引用形参在调用函数时,通过传递地址方式让形参成为实参的别名,不用生成临时变量,减少了时间和空间的开销。此外,如重载函数的返回值是对象引用时,返回的是对象,它可以出现在赋值号的左侧而成为左值,可以被赋值或参与其他操作(如保留,cout,流的当前值以便能连续使用,输出)。,4.8.1,标准类型数据间的转换,int,i=6;,i=7.5+i,;,编译过程:,7.5,作为,double,型数处理,求解表达式时,将,6,转换陈,double,,然后再和,7.5,相加,得到的,13.5,的值向整型变量,i,赋值时,先转换为,13,再赋值,这种转换是,c+,编译系统自动完成的,称为,隐式类型转换,。,C+,的显式类型转换,是一种人为的强制转换。,格式:,类型名,(,数据,),例如:,int,(,89.5,),C,语言中的采用形式,(,类型名,),数据,如:(,int,),89.5,C+,保留了,c,语言的用法,提倡用,c+,的方法,4.8.2,用转换构造函数进行类型转换,作用:将一个其它类型的数据转换成一个指定的类的对象。,转换构造函数只有一个形参,如,C,omplex,(,double r,),real=r,;,imag,=0,;,其作用就是将,double,型的参数,r,转换成,Complex,类的对象,C,omplex c1,(,3.5,);,/,建立一个对象,调用构造函数,可以用声明语句建立一个无名的,Complex,对象,如,Complex,(,3.6,),/,合法,但无法使用,可以在一个表达式中使用无名对象,如,c1=complex,(,3.6,);,/,假设,c1,已被定义为,Complex,类的对象,转换构造函数也是一种构造函数,它遵循构造函数的一般规则。,通常把有一个参数的构造函数用作类型转换,所以,称为转换构造函数。,注意:,转换构造函数只能有一个参数。如果有多个参数,就不是转换构造函数。原因是:如果有多个参数的话,究竟是把哪个参数转换成类的对象呢,使用转换构造函数将一个指定的数据转换成类的对象的方法如下:,(,1,)先声明一个类(如上面的,Complex,)。,(,2,)在这个类中定义一个只有一个参数的构造函数,参数的类型是需要转换的类型,在函数体中指定转换的方法。,(,3,)在该类的作用域内可以用以下形式进行类型转换:,类名,(,指定类型的数据,),不仅可以将一个标准类型数据转换成类对象,也可以将另一个类的对象转换成转换构造函数所在类的对象。,如:可以将一个学生类对象转换成教师类对象,可以在,Teacher,类中写出下面的构造函数:,Teacher(Student,&,s)num,=,s.num;strcpy(name,s.name);sex,=,s.sex,;,注意:,对象,s,中的,num,name,sex,必须是公有成员,否则不能被类外引用,。,4.8.3,用类型转换函数进行类型转换,作用:将一个类的对象转换成另一个类型的数据,格式:,o,perator,类型名,(),实现转换的语句,在函数名前面不能指定函数类型,函数没有参数,返回值的类型是由函数名中指定的类型名来确定的。类型转换函数只能作为成员函数,因为转换的主体是本类的对象。不能作为友元函数或普通函数。,转换构造函数和类型转换运算符的共同功能:,当需要的时候,编译系统会自动调用这些函数,建立一个无名的临时对象(或临时变量),例:,double d1,d2;Complex c1,c2;,假设类中定义了类型转换函数,对于表达式:,d1=d2+c1,;,编译系统发现“,+”,左侧的,d2,是,double,型,而右侧的,c1,是,Complex,类对象,如果没有对运算符“,+”,进行重载,就会检查有无类型转换函数,结果发现有对,double,的重载函数,就调用该函数,把,Complex,类对象,c1,转换为,double,型数据,建立一个临时的,double,变量,并与,d2,相加,最后将一个,double,型数据赋给,d1,。,如果类中已定义转换构造函数并重载了运算符“,+”,(作为,Complex,类的友元函数),但未对,double,定义类型转换函数(或者说未对,double,重载)对于表达式:,c2=c1+d2,;,编译系统怎样处理呢?,它发现运算符“,+”,左侧的,c1,是,Complex,类对象,右侧的,d2,是,double,型。,编译系统寻找有无对“,+”,的重载,发现有,operator+,函数,但它是,Complex,类的友元函数,要求两个,Complex,类的形参,即只能实现两个,Complex,类对象相加,而现在,d2,是,double,型,不合要求。,在类中没有对,double,进行重载,因此不可能把,c1,转换为,double,型数据然后相加。,编译系统就去找有无转换构造函数,发现有,就调用转换构造函数,Complex,(,d2,),建立一个临时的,Complex,类对象,在调用,operator+,函数,将两个复数相加,然后赋给,c2,。,相当于执行表达式:,c2=c1+Complex(d2),例,4.9,使用类型转换函数的简单例子,#include,using namespace std;,class Complex,public:,Complex()real,=0;imag=0;,Complex(double,r,double,i)real,=,r;imag,=i;,operator double()return real;,private:,double real;,double,imag,;,;,int,main(),Complex c1(3,4),c2(5,-10),c3;,double d;,d=2.5+c1;,cout,d,endl,;,return 0;,5.5,分析:,(,1,)如果在,Complex,类中没有定义类型转换函数,operator double,,程序编译将会出错。因为不能实现,double,数据类型与,Complex,类对象的相加。,(,2,)如果在,main,函数中加一语句:,c3=c2,;编译系统是把,c2,按,Complex,类对象处理,因为赋值号两侧为同一类数据,可以合法赋值。,(,3,)如果在,Complex,类中声明了重载运算符“,+”,函数作为友元函数,并在类外定义,operator+,函数:,Complex operator+,(,Complex c1,,,Complex c2,),return Complex,(,c1.real+c2.real,c1.imag+c2.imag,),;,c3=c1+c2;/,有运算符“,+”,重载,可以实现对象相加,d=c1+c2;/,先相加,再通过对,double,的重载函数将临时对象转化为,double,,再赋值,对类型的重载和对运算符的重载的概念和方法相似,重载函数都使用关键字,operator,,它的意思是“运算符”。因此,通常把类型转换函数也成为类型转换运算符函数,由于它也是重载函数,因此也称为类型转换运算符重载函数(或称强制类型转换运算符重载函数),例,4.10,包含转换构造函数、运算符重载函数和类型转换函数的程序,#include,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;,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+2.5;,c3.display();,return 0;,分析:,(,1,)如果没有转换构造函数,则此程序编译出错,因为没有重载运算符使之能将,Complex,类对象与,double,数据相加。,(,2,)由于重载了运算符“,+”,,表达式,c1+2.5,,编译系统解释为:,operator+,(,c1,2.5,),/2.5,不是,Complex,类对象,调用转换构造函数,Complex,(,2.5,),形成表达式:,operator+,(,c1,,,Complex,(,2.5,),(,3,)如果把“,c3=c1+2.5”,改为“,c3=2.5+c1”,。编译仍能通过。我们从中得到结论:在已定义了相应的转换构造函数情况下,,将运算符“,+”,函数重载为友元函数,在进行两个复数相加时,可以使用交换律,。,如果运算符“,+”,重载函数不作为,Complex,类的友元函数,而作为,Complex,类的成员函数,不能满足交换律。,函数的原型:,operator+,(,Complex c2,);,/Complex,类成员函数,函数第一个参数省略了,它隐含指,this,所指的对象。,对于表达式:,c1+2.5,c+,编译系统解释为:,c1.operator+(2.5),通过转换构造函数,Complex,(,2.5,),建立一个临时的,Complex,对象。则表达式相当于:,c1.operator+(Complex(2.5).,但对于表达式:,2.5+c1,。,C,+,系统解释为(,2.5,),.operator+(c1)/,错误,如果运算符函数重载为成员函数,它的第一个参数必须是本类的对象。当第一个操作数不是类对象时,不能将运算符函数重载为成员函数。,如果将运算符“,+”,函数重载为成员函数,交换律不适用,。,一般情况下,将双目运算符函数重载为友元函数。单目运算符则为重载成员函数。,(,4,)在上面的基础上增加类型转换函数:,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()cout,return real;,friend Complex operator+(Complex c1,Complex c2);,void display();,程序在编译时出错,原因是出现二义性。在处理,c1+2.5,时出现二义性。一种理解是:调用转换构造函数,把,2.5,变成,Complex,类对象,然后调用运算符“,+”,重载函数,与,c1,进行复数相加。,另一种理解是:把,c1,转换成,double,型数,然后与,2.5,进行相加。系统无法判定,这两者是矛盾的。,如果要使用类型转换函数,就应当删去运算符“,+”,重载函数。,
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 百科休闲 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服