已阅读5页,还剩70页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第10章运算符重载,10.1什么是运算符重载10.2运算符重载的方法10.3重载运算符的规则10.4运算符重载函数作为类成员函数和友元函数10.5重载双目运算符10.6重载单目运算符10.7重载流插入运算符和流提取运算符10.8不同类型数据间的转换,10.1什么是运算符重载,C+中预定义的运算符的操作对象只能是基本数据类型。但实际上,对于许多用户自定义的类型,也需要类似的运算。这时就必须重新定义这些运算符,赋于已有运算符新的功能,使之能够用于特定类型执行特定操作。,实际上,很多C+操作符已经被重载。例如,将*操作符用于地址,将得到在这个地址中的值;但将它用于两个数字时,得到的将是它们的乘积。C+根据操作数的数目和类型来决定采用哪种操作。,使同一个运算符作用于不同类型的数据时导致不同的行为的这种机制称为运算符重载。C+通过重载运算符使之用于自定义类型,扩展了运算符的功能,这也是C+最具吸引力的优点之一。,运算符重载机制,运算符重载是通过重载一种特殊函数运算符函数来实现的。对C+运算符可作如下理解:编译器在对运算符进行编译处理时,将一个运算符编译成如下形式:一元运算符:objoperator(obj)二元运算符:obj1obj2operator(obj1,obj2)由于C+中有前增(减)、后增(减),为了区分它们,C+将后增(减)编译成:后增:obj+operator+(obj,0)后减:obj-operator-(obj,0),依照上述规则,8+9、10.5+3.5分别编译成运算符函数调用形式为:operator+(8,9);operator+(10.5,3.5);C+为+运算符提供了多种运算符函数,其原型有:operator+(int,int);operator+(double,double);等,10.2运算符重载的方法,运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算。也就是说,运算符重载是通过定义函数实现的。运算符重载实质上是函数的重载。,重载运算符的函数一般格式如下:函数类型operator运算符名称(形参表列)对运算符的重载处理,#includeusingnamespacestd;classComplexdoublereal;doubleimag;public:Complex()real=0;imag=0;Complex(doubler,doublei):real(r),imag(i)friendComplexoperator+(Complex,Complexoperator+(Complex,intmain()Complexc1(3,4),c2(5,-10),c3;c3=c1+c2;coutc1=;c1.display();coutc2=;c2.display();cout、=运算符,运算符重载函数必须为类的成员函数。,为什么?,10.5重载双目运算符,双目运算符(或称二元运算符)是C+中最常用的运算符。双目运算符有两个操作数,通常在运算符的左右两侧,如3+5,a=b,i10等。在重载双目运算符时,不言而喻在函数中应该有两个参数。下面再举一个例子说明重载双目运算符的应用。,例,定义一个字符串类String,用来存放不定长的字符串,重载运算符“=”,“”,用于两个字符串的等于、小于和大于的比较运算。下面分几步来介绍编程过程。,先建立一个String类,#includeusingnamespacestd;classStringpublic:String()p=NULL;/默认构造函数String(char*str);/构造函数voiddisplay();private:char*p;/字符型指针,用于指向字符串;,String:String(char*str)/定义构造函数p=str;/使p指向实参字符串voidString:display()/输出p所指向的字符串coutp;,intmain()Stringstring1(Hello),string2(Book);string1.display();cout(String,String:String(char*str)/定义构造函数p=str;/使p指向实参字符串voidString:display()/输出p所指向的字符串cout(String,intmain()Stringstring1(Hello),string2(Book);coutstring2)endl;程序运行结果为1。其他两个运算符的重载如法炮制即可。,扩展到对3个运算符重载。,见教材P325通过这个例子,不仅可以学习到有关双目运算符重载的知识,而且还可以学习怎样去编写C+程序。这种方法的指导思想是:先搭框架,逐步扩充,由简到繁,最后完善。边编程,边调试,边扩充。千万不要企图在一开始时就解决所有的细节。类是可扩充的,可以一步一步地扩充它的功能。最好直接在计算机上写程序,每一步都要上机调试,调试通过了前面一步再做下一步,步步为营。,10.6重载单目运算符,单目运算符只有一个操作数,如!a,-b,classTimepublic:Time()minute=0;/默认构造函数sec=0;Time(intm,ints):minute(m),sec(s)/构造函数重载Timeoperator+();/声明运算符重载函数voiddisplay()coutminute:sec=60)sec-=60;/满60秒进1分钟+minute;return*this;/返回当前对象值,intmain()Timetime1(34,0);for(inti=0;i61;i+)+time1;time1.display();return0;,“+”和“-”运算符有两种使用方式,前置自增运算符和后置自增运算符,它们的作用是不一样的,在重载时怎样区别这二者呢?针对“+”和“-”这一特点,C+约定:在自增(自减)运算符重载函数中,增加一个int型形参,就是后置自增(自减)运算符函数。,例,在上例程序的基础上增加对后置自增运算符的重载。修改后的程序如下:,classTimepublic:Time()minute=0;/默认构造函数sec=0;Time(intm,ints):minute(m),sec(s)/构造函数重载Timeoperator+();/声明前置自增运算符+重载函数Timeoperator+(int);/声明后置自增运算符+重载函数voiddisplay()coutminute:sec=60)sec-=60;+minute;returntemp;/返回的是自加前的对象,可以看到:重载后置自增运算符时,多了一个int型的参数,增加这个参数只是为了与前置自增运算符重载函数有所区别,此外没有任何作用。编译系统在遇到重载后置自增运算符时,会自动调用此函数。,intmain()Timetime1(34,59),time2;couttime1:;time1.display();+time1;cout+time1:;time1.display();time2=time1+;couttime1+:;time1.display();cout”进行了重载,使之作为流插入运算符和流提取运算符,能用来输出和输入C+标准类型的数据。因此,凡是用“cout”对标准类型数据进行输入输出的,都要用#include把头文件包含到本程序文件中。,用户自己定义类型的数据,是不能直接用“”来输出和输入的。如果想用它们输出和输入自己声明的类型的数据,必须对它们重载。对“”重载的函数形式如下:istream重载运算符“”的函数的第一个参数和函数的类型都必须是istreamimag=0;Complex(doubler,doublei)real=r;imag=i;Complexoperator+(Complex,ComplexComplex:operator+(Complex,请思考:returnoutput的作用是什么?,intmain()Complexc1(2,4),c2(6,10),c3;c3=c1+c2;cout”,C+预定义的运算符“”的作用是从一个输入流中提取数据,如“cini;”表示从输入流中提取一个整数赋给变量i(假设已定义i为int型)。重载流提取运算符的目的是希望将“”用于输入自定义类型的对象的信息。,classComplexpublic:Complex()real=0;imag=0;Complex(doubler,doublei)real=r;imag=i;Complexoperator+(Complex,ComplexComplex:operator+(Complex,istream,intmain()Complexc1,c2;cinc1c2;coutc1=c1endl;coutc2=c2endl;return0;,10.8不同类型数据间的转换10.8.1标准类型数据间的转换,在C+中,某些不同类型数据之间可以自动转换,例如inti=6;i=7.5+i;编译系统对7.5是作为double型数处理的,在求解表达式时,先将6转换成double型,然后与7.5相加,得到和为13.5,在向整型变量i赋值时,将13.5转换为整数13,然后赋给i。这种转换是由C+编译系统自动完成的,用户不需干预。这种转换称为隐式类型转换。,C+还提供显式类型转换,程序人员在程序中指定将一种指定的数据转换成另一指定的类型,其形式为类型名(数据)如int(89.5)其作用是将89.5转换为整型数89。对于用户自己声明的类型,编译系统并不知道怎样进行转换。解决这个问题的关键是让编译系统知道怎样去进行这些转换,需要定义专门的函数来处理。,10.8.2转换构造函数,转换构造函数的作用是将一个其他类型的数据转换成一个类的对象。先回顾一下以前学习过的几种构造函数:默认构造函数。以Complex类为例,函数原型的形式为Complex();/没有参数用于初始化的构造函数。函数原型的形式为Complex(doubler,doublei);/形参表列中一般有两个以上参数用于复制对象的复制构造函数。函数原型的形式为Complex(Complex/形参是本类对象的引用,现在又要介绍一种新的构造函数转换构造函数。转换构造函数只有一个形参,如Complex(doubler)real=r;imag=0;其作用是将double型的参数r转换成Complex类的对象,将r作为复数的实部,虚部为0。用户可以根据需要定义转换构造函数,在函数体中告诉编译系统怎样去进行转换。,在类体中,可以有转换构造函数,也可以没有转换构造函数,视需要而定。以上几种构造函数可以同时出现在同一个类中,它们是构造函数的重载。编译系统会根据建立对象时给出的实参的个数与类型选择形参与之匹配的构造函数。,使用转换构造函数将一个指定的数据转换为类对象的方法如下:(1)先声明一个类。(2)在这个类中定义一个只有一个参数的构造函数,参数的类型是需要转换的类型,在函数体中指定转换的方法。(3)在该类的作用域内可以用以下形式进行类型转换:类名(指定类型的数据)就可以将指定类型的数据转换为此类的对象。,classComplexpublic:Complex():real(0),imag(0)Complex(doubler,doublei):real(r),imag(i)Complex(doubler):real(r),imag(0)Complexoperator+(Complexc2);friendostream,ComplexComplex:operator+(Complexc2)returnComplex(real+c2.real,imag+c2.imag);ostream,intmain()Complexc1(3,6),c2;c2=c1+(Complex)8.2;/c2=c1+Comples(8.2);/c2=c1+8;/c2=8+c1;coutc2endl;return0;,classComplexpublic:Complex():real(0),imag(0)Complex(doubler,doublei):real(r),imag(i)Complex(doubler):real(r),imag(0);friendComplexoperator+(Complexc1,Complexc2);friendostream,Complexoperator+(Complexc1,Complexc2)returnComplex(c1.real+c2.real,c1.imag+c2.imag);ostream,intmain()Complexc1(3,6),c2;c2=8+c1;/okcoutc2endl;return0;,对称运算符一般重载为友元函数。,10.8.3类型转换函数,用转换构造函数可以将一个指定类型的数据转换为类的对象。但是不能反过来将一个类的对象转换为一个其他类型的数据(例如将一个Complex类对象转换成double类型数据)。,C+提供类型转换函数(typeconversionfunction)来解决这个问题。类型转换函数的作用是将一个类的对象转换成另一类型的数据。类型转换函数的一般形式为operator类型名()实现转换的语句在函数名前面不能指定函数类型,函数没有参数。其返回值的类型是由函数名中指定的类型名来确定的。类型转换函数只能作为成员函数,因为转换的主体是本类的对象。,如果已声明了一个Complex类,可以在Complex类中这样定义类型转换函数:operatordouble()returnreal;double类型经过重载后,除了原有的含义外,还获得新的含义(将一个Complex类对象转换为double类型数据,并指定了转换方法)。这样,编译系统不仅能识别原有的double型数据,而且还会把Complex类对象作为double型数据处理。,那么程序中的Complex类对具有双重身份,既是Complex类对象,又可作为double类型数据。Complex类对象只有在需要时才进行转换,要根据表达式的上下文来决定。转换构造函数和类型转换运算符有一个共同的功能:当需要的时候,编译系统会自动调用这些函数,建立一个无名的临时对象(或临时变量)。,classComplexpublic:Complex():real(0),imag(0)Com
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 建筑钢材供货协议书
- 广告牌定制合同范本
- 扶贫设备补助协议书
- 承包土地代耕协议书
- 承包寺院合同协议书
- 承包政府场地协议书
- 承包水立方合同范本
- 承包矿渣合同协议书
- 承包资质协议书范本
- 承包餐厅协议书范本
- 2023云南省口腔种植医疗服务项目价格表pdf
- 2018年蜀都杯《辛亥革命》终稿z
- 家庭情绪表露问卷FEQ
- 西溪国家湿地公园规划设计分析课件
- 东宝秘浴内训版
- 广东区域地质构造简介之一-断裂特征介绍
- 机械原理课程设计-自动打印机设计说明书
- T-CAMET 04017.2-2019 城市轨道交通 全自动运行系统规范 第2部分:核心设备产品
- 二次回风空调过程计算
- 浙江政采云网上超全一张网供应商承诺书
- 《电路原理》课后习习题答案
评论
0/150
提交评论