




已阅读5页,还剩46页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第12章运算符重载和类型重载,主要内容:12.1运算符重载规则12.2类型重载,在C+中有这样的情况,同一个类型或运算符在不同的类中代表不同的意思或者实施不同的运算,这就是面向对象的三大特点之一的多态。函数重载是C+语言中多态的一种表现形式,运算符重载和类型重载是多态的另外两种表现形式。,运算符重载是对已有的运算符赋予多重含义。C+中预定义的运算符的操作对象只能是基本数据类型,对于很多用户自定义类型,也需要有类似的运算操作,这就提出了对运算符进行重新定义,赋予已有符号以新功能的要求。同一个运算符作用于不同类型的数据导致不同的行为。,12.1运算符重载概述,运算符重载只能对系统提供的已有运算定义新的运算含义,不能创造全新的运算符,同时还不能改变运算符原有的语法结构、操作数个数、优先级和结合性,不能有二义性。不是所有的运算符都能重载,不能重载的运算符有:作用域运算符(:)、条件运算符(?:)、直接成员访问运算符(.)、sizeof运算符、解除对指向类成员的指针的引用运算符(.*)。运算符重载的关键字是operator。针对一个具体类的已有运算符重载有两种途径:1)将运算符重新定义为类的成员函数;2)将运算符重新定义为类的友元函数。,一、运算符重载方法,定义一个重载运算符就像定义一个函数,只是该函数的名字是operator,这里代表运算符。函数参数表中参数的个数取决于两个因素:1)运算符是一元的(一个参数)还是二元的(两个参数)。2)运算符被定义为友元函数(对于一元是一个参数,对于二元是两个参数)还是成员函数(对于一元没有参数,对于二元是一个参数对象变为左侧参数)。,1.将运算符重载为类的成员函数,将运算符重载为类的成员函数就是在类中用关键字operator定义一个成员函数,函数名就是重载的运算符。运算符如果重载为类的成员函数,它就可以自由地访问该类的数据成员。运算符重载为类的成员函数的一般格式为::operator(形参表)函数体其中,类型为运算符重载函数的返回类型。类名为成员函数所属类的类名,即为重载函数名。形参为参加运算的对象或数据。,【例题12.1】复数的加减运算符重载,#includeusingnamespacestd;classComplexprivate:floatreal,image;public:Complex(floatr=0,floati=0);ComplexAdd(constComplex,Complex:Complex(floatr,floati)real=r;image=i;voidComplex:Show(inti)/一般情况下,这里不应该有参数i,本例的目的是为了区分不同的复数,便于观看结果cout0)cout+imageiendl;if(image0)coutimageiendl;,ComplexComplex:Add(constComplex,ComplexComplex:operator-(constComplex,intmain()Complexc1(12,35),c2(20,46),c3,c4,c5,c6;c1.Show(1);c2.Show(2);c3=c1.Add(c2);c3.Show(3);c4=c1+c2;c4.Show(4);c2+=c1;c2.Show(2);c5=c1-c2;c5.Show(5);return0;,如果我们把“operator+”看成函数名,可以在main()函数中写出如下语句:c3=c1.Add(c2);c3=c1.operator+(c2);这时,operator+就完全是一个函数了(它本质上就是函数),.Add()和operator+的作用和功能完全相同,只是表现形式有些区别。,【例题12.2】一元运算符重载,在Time类(描述时间的类,用三个数据成员分别存放时、分和秒)中重载自加运算符,即一个时间加上n秒后形成一个新的的时间。,classTimeprivate:inthour,minute,second;public:Time(inth=0,intm=0,ints=0);/其他构造函数省略如Time(Time,Time:Time(inth,intm,ints)hour=h;minute=m;second=s;voidTime:Show()couthour:minute:secondendl;,Time,TimeTime:operator+(int)/返回原来的值,再加Timetemp=*this;second+;if(second=60)second=0;minute+;if(minute=60)minute=0;hour+;if(hour=24)hour=0;returntemp;,Time,intmain()Timet1(10,25,52),t2,t3;t1.Show();t2=+t1;t1.Show();t2.Show();t3=t1+;t3.Show();t1.Show();,对于+(或-)运算符的重载,因为编译器不能区分出+(或-)是前置的还是后置的,所以要加上(int)来区分。operator+();/重载前置+operator+(int);/重载后置+operator-();/重载前置-operator-(int);/重载后置-,运算符重载的一些特点如下:(1)运算符重载函数名必须为:operator。(2)运算符的重载是通过运算符重载函数来实现的。对于二元运算符重载函数,函数的参数通常为一个即右操作数,运算符的左操作数为调用重载函数的对象。对于一元运算符重载函数,运算符的左操作数或右操作数为调用重载函数的对象。(3)运算符重载函数的返回类型:若对象进行运算后的结果类型仍为原类型,则运算符重载函数的返回类型应为原类型。,【例11.3】自定义字符串类String中有一个private成员p_str指向一个C格式的字符串,写出其拷贝构造函数,并重载赋值“=”运算符。,#include#includeusingnamespacestd;classStringpublic:String()p_str=NULL;String(constString,String:String(constchar*str)p_str=newcharstrlen(str)+1;strcpy(p_str,str);String:String(constString,String,赋值运算符重载一般包括以上几个步骤,首先要检查是否自赋值,如果是要立即返回,如果不返回,后面的语句会把自己所指空间删掉,从而导致错误;第二步要释放原有的内存资源;第三步要分配新的内存资源,并复制内容;第四步是返回本对象的引用。如果没有指针操作,则没有第二步操作。赋值运算符与拷贝构造函数在功能上有些类似,都是用一个对象去填另一个对象,但拷贝构造函数是在对象建立的时候执行,赋值运算符是在对象建立之后执行。,2将运算符重载为类的友元函数,二元运算符重载为友元函数的一般格式为:friendoperator(,);operator(,)函数体;一元运算符重载为友元函数的一般格式为:operator(类名classComplexprivate:floatreal,image;public:Complex(floatr=0,floati=0);friendComplexoperator+(constComplex,Complex:Complex(floatr,floati)real=r;image=i;voidComplex:Show(inti)cout0)cout+imageiendl;if(image0)coutimagei=,由istream重载为提取操作,用于输出和输入基本类型数据。可用重载运算符,用于输出和输入用户自定义的数据类型,必须定义为类的友元函数。,4.重载流插入和流提取运算符,1)输出操作符的重载输出操作符重载函数形式为:ostream第一个参数和函数的类型都必须是ostreamclassDatepublic:Date(inty,intm,intd);boolisLeapYear();voidprint();friendostream#endif/DATE_H_INCLUDED,【例11.7】为Date类重载提取运算符(ex004.cpp),#include#includeDate.husingnamespacestd;Date:Date(inty,intm,intd)year=y;month=m;day=d;boolDate:isLeapYear()return(year%4=0,voidDate:print()coutyear-month-dayendl;ostream,#include#includeDate.husingnamespacestd;intmain()Dated1(2013,4,1);coutd1;return0;,在重载函数中,由于operator()函数是Date类的友元函数,因此在使用Date类的数据成员和成员函数时必须指定对象。一般而言,输出操作符应该输出对象的内容,进行最小限度的格式化,不应该输出换行符。在主函数(main)中,cout的值被传递给output。由于函数返回的是ostream对象的引用,所以在主函数中可以将”的重载输入操作符重载函数形式为:istream与输出操作符类似,输入操作符的第一个形参是一个引用,指向要读的流,并且返回的也是同一个流的引用。第二个形参是对要读入的对象的非const引用,该形参必须为非const,因为输入操作符的目的是将数据读到这个对象中。和输出操作符不同的是输入操作符必须处理错误和文件结束的可能性。,【例题11.8】重载输入操作符,在上例的基础上加上Date类对象能用“”输入数据。,classDatepublic:Date()year=0;month=0;day=0;Date(inty,intm,intd);Date(strings);boolisLeapYear();private:intyear;intmonth;intday;friendostream,istream,intmain()Dated1(2013,3,20);coutd2;coutd2endl;return0;,输入操作符将读入所期望的值并检查是否发生错误。可能发生的错误有:1)提供的值不正确。如Date类对象中如果输入了字符型数据,读入以及流的后续使用都将失败。2)任何读入都可能碰到输入流中的文件结束或其他一些错误。如果输入操作符检测到输入失败了,则确保对象处于可用和一致的状态是个好做法。如果对象在错误发生之前已经写入了部分信息,这样做就特别重要。因此设计输入操作符时,如果可能,要确定错误恢复措施,这是很重要的。例题11.8中如果输入出现错误,将对象中的数据成员都设置为0,使得对象仍然处于可用状态,同时也不会产生令人误解的结果。,12.2类型重载,C+中提供了类型转换函数,可以将一种类类型对象转换成另一种类类型的对象,这就是类型重载。类型转换函数必须由用户在类中定义为成员函数,其一般格式为:classpublic:operator();:operator()函数体;其中operator为转换函数的函数名,转换函数的作用是将类型1的对象转换成类型2的对象。类中类型转换函数必须是非静态的成员函数,不能定义成友元函数,无返回值类型且不带参数。,【例11.9】定义一个时间类,类中数据成员为时、分、秒。编写类型转换函数,将时、分、秒变成一个以秒为单位的等价实数。,#includeusingnamespacestd;classTimeprivate:inthour,minute,second;public:Time(inth=0,intm=0,ints=0);voidShow();/显示时:分:秒的成员函数operatorfloat();Time:Time(inth,intm,ints
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 磺胺醋酰钠对生物体内药物代谢途径的研究-洞察及研究
- 基因编辑技术在生物进化研究中的应用-洞察及研究
- 肩关节盂肱关节囊与肩关节退行性病变关联-洞察及研究
- 网络成瘾的心理分析及其干预措施-洞察及研究
- 针灸推拿与心理健康相关性研究-洞察及研究
- 肩关节盂肱关节囊损伤与肩痛相关性分析-洞察及研究
- 铁路信息化系统集成-洞察及研究
- 掌长肌肌电图异常模式分类-洞察及研究
- 建筑施工安全检查周报范本
- 小学教师年度工作总结及经验分享
- 2025浙江杭州建德市乡镇(街道)辅助性岗位集中招聘工作人员47人备考考试题库附答案解析
- 铜排制作工艺流程图制作
- 通信登高作业安全培训课件
- 肝硬化并发症课件
- 2025广东广州市白云区民政局招聘窗口服务岗政府雇员1人笔试参考题库附答案解析
- 古希腊史诗与戏剧课件
- 腹股沟疝修补术护理查房
- 创伤应急预案演练脚本(2篇)
- 信息运维服务管理规范标准
- 2025年中级注册安全工程师《安全生产管理》考前三十页纸
- 新教材2025-2026学年人教版(2024)美术二年级上册全册(教学设计)教案
评论
0/150
提交评论