




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C++面向对象程序设计第十章运算符重载与类模板1精选课件学习目标⑴理解为什么要进行运算符重载,在什么情况下要进行运算符重载⑵掌握通过成员函数重载运算符,借助友元函数实现运算符重载⑶理解引用在运算符重载中的作用,引用作为参数和返回值的好处和用法⑷理解类型转换的必要性,能够在程序设计中正确应用类型转换⑸理解为什么要引入类模板的概念,掌握类模板的应用2精选课件10.1为什么要进行运算符重载10.1.1运算符重载的例子 在程序中,经常会使用运算符,但C++中已经定义的运算符都是针对基本数据类型的,那么能否将它们用于复杂的类对象呢?在学习本章之前,我们往往是编写实现相应运算功能的函数来解决复杂类型的运算问题。首先来看一个复数加法运算的例子,请注意程序中,加法运算时表达式的书写形式。【例6-1】复数的加运算。见教材P1333精选课件程序说明: 在【例10-1】为了解决复数的存储问题,在复数类Complex中,定义了两个私有成员变量:real(复数的实部)和imag(复数的虚部);并定义了公有的复数加法函数add()和友元输出函数print()显示复数。在main函数中定义了三个复数对象,使用加法函数add进行3个复数的相加,并输出结果。 在程序中三个复数相加的表达式为: c4=c1.add(c2).add(c3); 用这种方式书写表达式,不仅形式复杂、不符合人们的日常书写习惯,而且不易理解;复数的运算越复杂,书写的表达式越困难,给使用自定义类编写程序带来诸多不便。如果能够像使用基本类型那样用运算符来书写复数运算表达式(如c4=c1+c2+c3;),不仅书写简单,也更容易理解;这正是在C++中引入了运算符重载的意义所在。下面通过使用运算符重载进行复数加运算例子来了解如何进行运算符的重载。4精选课件【例10-2】使用运算符重载进行复数加运算见教材P134输出结果:11+2i程序说明: 该程序的作用和【例10-1】相同,只是用运算符重载函数代替了加法函数。 比较两个程序不难发现,【例10-2】中书写的复数相加表达式,含义清晰,便于书写。让复数类的使用变得更加简易。 程序中“+”运算符重载的定义如下: Complexoperator+(Complex&c); 它与一般函数的定义非常相似,不同的是运算符重载函数的名字(“operator+”)是由“operator”关键字和紧随其后的运算符“+”组成;关键字“operator”表明该函数是一个运算符重载函数。在【例10-2】中,该函数是作为类Complex的成员函数,因此把以这种方式的运算符重载称作重载为类运算符。5精选课件【例10-3】重载为友元运算符进行复数加运算见教材P136 输出结果:11+2i 程序说明: 本例实现的功能与【例10-1】和【例10-2】完全相同。 本例中,“+”运算符重载函数的定义如下: Complexoperator+(Complex&c1,Complex&c2); 由于该函数是一般的普通函数,不是类的成员函数,只是为能够访问类的私有数据成员,而把其声明为类的友元函数,因此在定义时参数表中必须指定两个参数:第1个参数作为运算符的左操作数,第2参数作为运算符的右操作数。6精选课件10.1.2注意事项C++对运算符重载作出了一定的限制和规定,在重载运算符时,需要注意以下几点: ⑴不是所有运算符都可以被重载。C++的大部分运算符都可以被重载。可以重载的运算符如下:newnew[]deletedelete[]+-*/%^&|~=<>+=-=*-/=%=^=&=|=<<>>&&||++--->*->()[]其中,运算符()是函数调用运算符,[]是下标运算符。+、-、*和&的一元、二元形式都可以被重载。自增运算符++和自减运算符--的前置、后置形式都可以被重载。以上可重载运算符中,除了赋值运算符"="之外,基类中所有被重载的运算符都将被派生类继承。7精选课件不可以重载的运算符如下:.(成员运算符).*(成员对象选择符)::(解析运算符)?:(条件运算符)⑵重载不能改变运算符的优先级。假定已定义了复数类Complex,并且已定义了加法和乘法运算符重载函数,Complexc1(1,2),c2(3,4),c3(5,6),answer;answer=c1+c2*c3;在这个表达式中,乘法运算优先级高于加法运算,它等效于answer=c1+(c2*c3);如同系统定义数据类型一样,可以使用括号强制改变重载运算符的计算顺序,例如:answer=(c1+c2)*c3;⑶重载不能改变运算符的结合律。8精选课件⑷重载不能改变运算符的操作数个数。重载的一元运算符仍然是一元运算符,重载的二元运算符仍然是二元运算符。C++中唯一的三元运算符(?:)不能被重载。运算符+、-、*、&和~既可以用作一元运算符和二元运算符,对这几个运算符,要分别把他们重载为一元运算符和二元运算符。⑸不能创建新的运算符,只有现用的运算符才能被重载。⑹运算符重载函数的参数至少有一个必须是类的对象或者是类的对象的引用。⑺运算符只能被显式重载(不存在隐式重载),例如,运算符"+"和"="已被分别重载,这不意味着运算符"+="或"=="已被重载。⑻运算符重载函数不能带有缺省参数。⑼重载运算符时,要保持语义上的一致性。例如,重载运算符"+"时,仍应对有关对象执行加法运算。当然,也可以定义为其它某种运算,但这样做既没有必要,也容易造成混乱。⑽C++规定,“=、()、[]、->”四种运算符必须重载为类运算符。9精选课件10.2赋值运算符和四则运算符的重载 对名为T的类,其赋值运算符重载函数的格式如下: Toperator=(T&); 由于赋值运算符只能重载为类运算符,所以这是赋值运算符重载函数的唯一格式。 对名为T的类,其二元运算符(用#表示)重载函数的格式如下: Toperator#(T&);//重载为类成员运算符 或 Toperatore#(T&,T&);//重载为非类成员运算符 四则运算符属于二元运算符,也可以使用这两种形式。 下面仍以复数运算为例,说明赋值运算符和四则运算符的重载。 【例10-4】复数的四则运算见教材P13810精选课件10.3自增1和自减1运算符重载自增1运算符“++”和自减1运算符“--”都各有两种形式:前缀(前运算)和后缀(后运算)。例如,++a是前运算符:在进行其他运算前,变量a首先增1。a++是后运算符:做完其他运算后,a才增1。这四种形式的每一种都可以重载。增1运算符和减1运算符都只有一个操作数,通常被重载为类运算符。一元类运算符重载函数的参数表理应没有参数(操作数即是类对象本身),但为了区分前运算和后运算这两种形式,C++中规定:前运算符重载函数的参数表没有参数;后运算符重载函数的参数表设一个整数参数,这个参数称为哑元,只作为一个标志,用以区别前运算符。所以,对名为T的类,重载前运算符和后运算符的函数原型取如下格式:Toperator++();//重载前增1运算符Toperator++(int);//重载后增1运算符Toperator--();//重载前减1运算符Toperator--(int);//重载后减1运算符为了说明增1运算符和减1运算符重载,下面给出一个分数类作自增,自减的例子。【例6-5】分数类的自增,自减。见教材P14211精选课件10.4关系运算符的重载在C++中对于使用内部数据类型定义的变量,可以使用六个关系运算符“<、>、<=、>=、==和!=”进行比较运算。而要对自定义类定义的变量进行比较运算,用户就必须重载这些运算符。下面以分数的>为例说明关系运算符的重载。【例10-6】比较两个分数大小,输出值大的分数。见教材P14412精选课件10.5算术赋值运算符的重载在C++中允许把算术运算符和赋值运算符组合在一起使用,这种书写方法简洁高效;同样也可以在自定义类型中重载这些运算符。为了简单起见,仍然使用分数的例子。【例10-7】分数的加法运算。见教材P14513精选课件10.6下标运算符的重载“[]”下标运算符通常用于数组,c++也允许重载这个运算符,在重载这个运算符时,需要注意的是:当“[]”运算符位于“=”左边时,是修改数组中元素的值,需要返回这个元素的指针或引用;当“[]”运算符位于“=”右边时,是取得数组中元素的值,需要返回这个元素的值或引用;为了能使“[]”运算符即可用于“=”左边,也可用于“=”右边,在重载“[]”运算符时,必须返回该元素的引用。下面给出一个数组类的例子来说明这一问题。 【例10-8】一个数组类的例子。见教材P14714精选课件10.7插入与抽取运算符的重载10.7.1插入运算符的重载 C++中对左移运算符“<<”进行重载,以便输出C++内部类型的数据。对于自定义类型也可以重载运算符“<<”,按照合适的方式输出自定义类型的对象。下面以分数的输出为例介绍。【例10-9】分数的输出。见教材P14915精选课件10.7.2抽取运算符的重载C++中对右移运算符“>>”进行重载,以便把外来的信息输入到所有的C++内部数据类型的变量,这些重载函数作为系统类的成员函数。例如,如果i是一个整型变量,C++便将输入语句cin>>i;翻译为cin.operator>>(i);然后调用此函数,读取一个值,存入变量i中。为了支持自定义类型,用户应重载输入运算符“>>”。在重载时,如果作为一般的函数来定义(而非类的成员函数),则这个重载运算符在被使用时应被声明为类的友元运算符。因为“>>”的第一个操作数是系统类的对象cin(系统类iostream的对象),因此,作为友元函数,类X的输入运算符重载函数的原型应为:istream&operator>>(istream&,X&);请注意:这个函数的第一个参数是输入流的引用,第二个参数是类X的引用。函数返回输入流的引用,其目的是为了能连续输入。对此,可以仿照6.7.1节做出解释。【例10-10】分数的输入。见教材P15116精选课件10.8类型转换 在C++中,当使用数值类型进行计算时,各种类型之间可以隐式或强制转换;例如: doubled; inta=2; d=a+5.3; 这种书写方式,使代码看起来优雅而自然。在用户自定义类中,没有进行类似的定义而无法使用这种方法。17精选课件10.8.1基本类型转换和自定义类型的相互转换在定义了类型转换后,对所有TRangeInt类型变量的计算都可以先转换成int类型,再进行计算,因此,可以不需要进行运算符的重载(如下面例子中的“+”、“-”运算符)。【例10-11】TRangeInt类型的加、减运算。见教材P15418精选课件10.8.2自定义类型之间的转换有两种方法可以实现自定义类型之间的转换:使用类型转换符函数和构造函数。不仅可以在基本类型转换和自定义类型之间实现类型的转换,也可以在两个自定义类型之间实现。【例10-12】使用类型转换符函数实现二维向量类型和复数类型的相互转换。见教材P15519精选课件【例10-13】使用构造函数实现二维向量类型和复数类型的相互转换。程序见教材P15720精选课件10.9类模板与模板类在编写程序时,有许多类的工作机制是相同的,只是其使用的数据类型不同。链表就是一个较为典型的例子,可以有整型链表、结构链表或自定义类的链表,但就链表本身的操作来说是相同的。在链表操作时,如果能够把要处理的类型当作参数,就可以构建一个通用的链表类。类模板的定义格式如下:template<classT>class类名{……}21精选课件这里template<classT>是指出在所定义的类中,将使用到一个参数的类型为T;编译时,类型T将被调用时的具体类型替换,产生一个具体的类,称为模板类(由模板产生的类)。来看一个具体的例子:单向链表,其结构图6.1所示。这里的数据可以是任意类型的,而对于任一个单向链表,其操作都是相同的;单向链表都具有增加、删除、寻找、遍历等操作链首指针节点指针数据节点指针数据节点指针数据图10.1单向链表22精选课件【例10-14】通用链表类的定义。程序见教材P15923精选课件本章小结本章介绍了C++中,运算符重载和类型转换的概念,举例说明了运算符重载和类型转换的用法。使用运算符重载可以使程序易于理解并易于对对象进行操作。几乎所有的C++运算符都可以被重载。如果在类中没有说明本身的拷贝构造函数和赋值运算符,编译程序将会提供,但它们都只是对对象进行成员浅拷贝。this指
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 市场营销在职工作证明(7篇)
- 月收入与奖金津贴明细证明书(6篇)
- 商业合作伙伴资信证明书(5篇)
- 市场需求导向下的农民素质提升路径
- 世界历史冷战时期事件考察试题集
- 促进教师专业发展提升美育教学质量的策略
- 汽车零部件供应协议
- 食品原料采购安全合同书
- 2025年艺术设计专业考试试题及答案回顾
- 2025年网络信息安全与技术防范的实务能力考试试卷及答案
- 岐黄天使中医西学中专项128学时试题答案
- 软件使用授权书
- 经济学基础题库-选择判断题库(401道)
- 敦煌壁画中的莲花图像
- 医院护理培训课件:《跌倒坠床PDCA分析》
- 国开《民法学(1)》形考任务1-4答案
- 热力发电厂课程设计说明书
- 阶梯轴的机械加工工艺过程卡片
- 特发性矮小病例分享
- 气体吸收操作-吸收塔结构认知(化工单元操作课件)
- 2023年副主任医师(副高)-中西医结合内科学(副高)考试参考题库附带答案
评论
0/150
提交评论