第6章多态性和虚函数.ppt

上传人:石*** 文档编号:87167151 上传时间:2023-04-16 格式:PPT 页数:27 大小:1.32MB
返回 下载 相关 举报
第6章多态性和虚函数.ppt_第1页
第1页 / 共27页
第6章多态性和虚函数.ppt_第2页
第2页 / 共27页
点击查看更多>>
资源描述

《第6章多态性和虚函数.ppt》由会员分享,可在线阅读,更多相关《第6章多态性和虚函数.ppt(27页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、第第6章多态性和虚函数章多态性和虚函数现在学习的是第1页,共27页多态性多态性不同的对象接收到相同的消息时产生多种完全不同不同的对象接收到相同的消息时产生多种完全不同的行为的现象称为多态性。的行为的现象称为多态性。C+支持两种多态性支持两种多态性:编译时的多态性和运行时多态性。编译时的多态性和运行时多态性。编译时的多态性使用重载来获得,运行时的多态性通过使编译时的多态性使用重载来获得,运行时的多态性通过使用继承和虚函数获得。用继承和虚函数获得。C+语言中,重载包括函数重载和运算符重载。语言中,重载包括函数重载和运算符重载。现在学习的是第2页,共27页6.16.1运算符重载运算符重载6.1.16

2、.1.16.1.16.1.1运算符重载概述运算符重载概述运算符重载概述运算符重载概述6.1.26.1.2用成员函数重载运算符用成员函数重载运算符6.1.36.1.36.1.36.1.3用友元函数重载运算符用友元函数重载运算符用友元函数重载运算符用友元函数重载运算符6.1.46.1.4几个常用运算符的重载几个常用运算符的重载现在学习的是第3页,共27页6.1.16.1.1运算符重载概述运算符重载概述1.1.运算符重载定义运算符重载定义C+中预定义的运算符的操作对象只能是基本数据类型,中预定义的运算符的操作对象只能是基本数据类型,运算符重载是对运算符进行重新定义,赋予已有符号新功运算符重载是对运算

3、符进行重新定义,赋予已有符号新功能的要求。能的要求。不能重载的运算符不能重载的运算符是:是:(1)(1)成员访问运算符成员访问运算符.(2)(2)作用域运算符作用域运算符(3)(3)条件运算符条件运算符?:?:(4)(4)成员指针运算符成员指针运算符*(5)(5)编译预处理命令的开始符号编译预处理命令的开始符号#现在学习的是第4页,共27页2.2.运算符重载的规则运算符重载的规则 C+中中的的运运算算符符除除了了少少数数几几个个以以外外,几几乎乎全全部部可可以以重重载载,程序员不能定义新的运算符,只能重载已有的这些运算符。程序员不能定义新的运算符,只能重载已有的这些运算符。重载之后运算符的优先

4、级和结合性都不能改变。重载之后运算符的优先级和结合性都不能改变。运运算算符符重重载载是是针针对对新新类类型型数数据据的的实实际际需需要要,对对原原有有运运算算符符进行适当的改造。进行适当的改造。3.3.运算符重载的形式运算符重载的形式 运运算算符符重重载载可可以以使使用用成成员员函函数数和和友友元元函函数数两两种种形形式式。运算符重载的实质就是函数重载。运算符重载的实质就是函数重载。现在学习的是第5页,共27页6.1.26.1.2用成员函数重载运算符用成员函数重载运算符在类定义体中声明运算符函数的形式为在类定义体中声明运算符函数的形式为:typeoperator(参数表参数表)其中其中为为运算

5、符符号运算符符号 若运算符是一元的,则参数表为空,此时当前对象作为此运算符的若运算符是一元的,则参数表为空,此时当前对象作为此运算符的单操作数;若运算符是二元的,则参数表中有一个操作数,此时当前对单操作数;若运算符是二元的,则参数表中有一个操作数,此时当前对象作为此运算符的左操作数,参数表中的操作数作为此运算符的右操作象作为此运算符的左操作数,参数表中的操作数作为此运算符的右操作数。数。运算符函数的定义如下:运算符函数的定义如下:type类名类名:operator(参数表)参数表)/运算符处理程序代码运算符处理程序代码 重重载载运运算算符符的的使使用用方方法法同同原原运运算算符符一一样样,只只

6、是是它它的的操操作作数数一一定定要要是是定义它的特定类的对象。定义它的特定类的对象。现在学习的是第6页,共27页l【例【例6.16.1】用成员函数重载运算符】用成员函数重载运算符+l#includelclasspointlprivate:lfloatx,y;lpublic:lpoint(floatxx=0,floatyy=0)x=xx;y=yy;lfloatget_x()returnx;lfloatget_y()returny;lpointoperator+(pointq);/重载运算符重载运算符“+”l;lpointpoint:operator+(pointq)lreturnpoint(x+

7、q.x,y+q.y);lvoidmain()lpointp1(3,3),p2(2,2),p3;/声明声明point类的对象类的对象lp3=p1+p2;或或p1.operator+(p2)/两点相加两点相加lcoutp1+p2:x=p3.get_x(),y=p3.get_y()endl;l现在学习的是第7页,共27页l【例【例6.6.2】用成员函数重载运算符用成员函数重载运算符+l#includepointpoint:operator+()lclasspointl+x;lprivate:+y;lfloatx,y;return*this;lpublic:lpoint(floatxx=0,float

8、yy=0)x=xx;y=yy;lfloatget_x()returnx;lfloatget_y()returny;lpointoperator+();/重载前置运算符重载前置运算符“+”l;lvoidmain()lpointp1(10,10);l+p1;或或lcoutp1:x=p1.get_x(),y=p1.get_y()endl;l现在学习的是第8页,共27页6.1.36.1.3用友元函数重载运算符用友元函数重载运算符friendtypeoperator(参数表参数表););注意友元函数不属于任何类,它没有注意友元函数不属于任何类,它没有this指针指针,这与成,这与成员函数完全不同。若运算

9、符是一元的,则参数表中有一个操员函数完全不同。若运算符是一元的,则参数表中有一个操作数;若运算符是二元的,则参数表中有两个操作数。作数;若运算符是二元的,则参数表中有两个操作数。友元友元运算符函数与成员运算符函数的主要区别在其参数个数运算符函数与成员运算符函数的主要区别在其参数个数不同不同。友元运算符函数的定义如下:友元运算符函数的定义如下:typeoperator(参数表参数表)/运算符处理程序代码运算符处理程序代码 现在学习的是第9页,共27页l【例【例6.6.3】用友员函数重载运算符用友员函数重载运算符+l#includelclasspointlprivate:lfloatx,y;lpu

10、blic:lpoint(floatxx=0,floatyy=0)x=xx;y=yy;lfloatget_x()returnx;lfloatget_y()returny;lfriendpointoperator+(pointp1,pointp2);/重载运算符重载运算符“+”l;lpointoperator+(pointp1,pointp2)lreturnpoint(p1.x+p2.x,p1.y+p2.y);lvoidmain()lpointp1(3,3),p2(2,2),p3;/声明声明point类的对象类的对象lp3=p1+p2;或或operator+(p1,p2)/两点相加两点相加lcou

11、tp1+p2:x=p3.get_x(),y=p3.get_y()endl;l现在学习的是第10页,共27页6.1.46.1.4几个常用运算符的重载几个常用运算符的重载2前自增和后自增运算符前自增和后自增运算符+的重载的重载前自增运算符前自增运算符+和后自增运算符和后自增运算符+重载的语法重载的语法 operator+();/operator+();/前前 operator+(operator+(intint);/);/后后课本课本P147P147【例【例6.76.7】用成员函数重载前自增和后自增运算符。】用成员函数重载前自增和后自增运算符。【例【例6.86.8】用友元重载前自增和后自增用友元重

12、载前自增和后自增 现在学习的是第11页,共27页6.26.2虚函数虚函数6.2.16.2.1为什么要引入虚函数为什么要引入虚函数6.2.26.2.2虚函数的定义与使用虚函数的定义与使用现在学习的是第12页,共27页6.2.16.2.1为什么要引入虚函数为什么要引入虚函数指向基类对象的指针都可以指向它的公有派生类对象,但不指向基类对象的指针都可以指向它的公有派生类对象,但不能指向它的私有派生类对象。能指向它的私有派生类对象。不能将一个声明为指向派生类对象的指不能将一个声明为指向派生类对象的指针指向其基类的一个对象。针指向其基类的一个对象。声声明明为为指指向向基基类类对对象象的的指指针针,当当它它

13、指指向向公公有有派派生生类类对对象象时时,只只能能利利用用它它来来直直接接访访问问派派生生类类中中从从基基类类继继承承来来的的成成员员,不不能能直直接接访访问问公公有派生类中特定的成员。有派生类中特定的成员。若若想想访访问问其其公公有有派派生生类类的的特特定定成成员员,可可以以将将基基类类指指针针显显式式类类型转换为派生类指针来实现。型转换为派生类指针来实现。【例【例6.146.14】引入虚函数举例引入虚函数举例现在学习的是第13页,共27页l【例【例6.6.14】引入虚函数举例引入虚函数举例l#includelclassbaselpublic:lvoidwho()lcoutthisisthe

14、classofbase!endl;lclassderive1:publicbaselpublic:lvoidwho()lcoutthisistheclassofderive1!endl;lclassderive2:publicbaselpublic:lvoidwho()lcoutthisistheclassofderive2!who();lderive1obj2;p=&obj3;lderive2obj3;p-who();lp=&obj1;(derive2*)p)-who();lp-who();obj2.who();lp=&obj2;obj3.who();lp-who();现在学习的是第14页,

15、共27页6.2.26.2.2虚函数的定义与使用虚函数的定义与使用11虚函数的定义虚函数的定义 虚虚函函数数定定义义是是在在基基类类中中进进行行的的(virtual),虚虚函函数数提提供供了了一一种种接接口口界界面面。在在基基类类中中的的某某个个成成员员函函数数被被声声明明为为虚虚函函数数后后,在在派派生生类类中中重重新新定定义义虚虚函函数数时时,都都必必须须与与基基类类中中的的原原型完全相同型完全相同。虚函数是一种非静态的成员函数,说明虚函数的方法虚函数是一种非静态的成员函数,说明虚函数的方法如下:如下:virtual类型函数名(参数表)类型函数名(参数表)现在学习的是第15页,共27页2.2

16、.虚函数与重载函数的关系虚函数与重载函数的关系(1)(1)重重载载函函数数要要求求函函数数有有相相同同的的函函数数名名称称,但但是是形形参参的的个个数数或或者者类类型型不不应应相相同同;而而虚虚函函数数则则要要求求函函数数名名、返返回回值值类类型型和和参数完全相同;参数完全相同;(2)(2)重重载载函函数数可可以以是是成成员员函函数数或或友友员员函函数数,而而虚虚函函数数只只能能是成员函数;是成员函数;(3)(3)重重载载函函数数的的调调用用是是以以所所传传递递参参数数序序列列的的差差别别作作为为调调用用不不同同函函数数的的依依据据;虚虚函函数数是是根根据据对对象象的的不不同同去去调调用用不不

17、同类的虚函数;同类的虚函数;(4)(4)虚函数在运行时表现出多态功能,这是虚函数在运行时表现出多态功能,这是C+的精髓;而的精髓;而重载函数则在编译时表现出多态性。重载函数则在编译时表现出多态性。现在学习的是第16页,共27页l【例【例6.6.15】虚函数与重载函数的关系虚函数与重载函数的关系虚函数与重载函数的关系虚函数与重载函数的关系l#includevoidmain()lclassbaselbaseobj1,*ptr;lpublic:deriveobj2;lvirtualvoidf1()ptr=&obj1;lcoutf1functionofbasef1();lvirtualvoidf2()

18、ptr-f2();lcoutf2functionofbasef3();lvirtualvoidf3()ptr=&obj2;lcoutf3functionofbasef1();lvoidf4()ptr-f2();lcoutf4functionofbasef4();l;lclassderive:publicbaselvoidf1()/仍为虚函数仍为虚函数lcoutf1functionofderive!endl;lvoidf2(intx)/丢失虚特性丢失虚特性lcoutf2functionofderiveendl;l/intf3()错误,只有返回类型不同错误,只有返回类型不同l/coutf3func

19、tionofderiveendl;lvoidf4()lcoutf4functionofderiveendl;l;现在学习的是第17页,共27页3 3虚函数的使用虚函数的使用 定定义义一一个个基基类类的的对对象象指指针针或或引引用用便便可可使使其其在在需需要要时时指指向向相相应应的的派派生生类类对对象象,可可以以调调用用该该对对象象所所对对应应的的类类中中已已被被“虚虚拟化拟化”的函数,从而实现真正的运行时的多态性。的函数,从而实现真正的运行时的多态性。【例【例6.166.16】虚函数的使用举例。虚函数的使用举例。注注意意:在在构构造造函函数数中中出出现现虚虚函函数数,虚虚函函数数的的调调用用采

20、采用用静静态态联联编编,即即它它们们所所调调用用的的虚虚函函数数是是基基类类中中定定义义的的函函数数而而不不是是在在任任何派生类中重定义的函数。何派生类中重定义的函数。现在学习的是第18页,共27页l【例【例6.6.16】虚函数的使用举例虚函数的使用举例l#includevoidmain()lclassAlAa;lpublic:Bb;lA()A*p=&b;l couttheconstructorofclassAf();lf();p-g();lvirtualvoidf()p-h();lcoutA:f()endl;a.f();lvoidg()a.g();lcoutA:g()endl;a.h();l

21、voidh()b.f();lcoutA:h()endl;b.g();lf();g();b.h();l;lclassB:publicAllpublic:lvoidf()lcoutB:f()endl;lvoidg()lcoutB:g()endl;l;现在学习的是第19页,共27页4.在构造函数和析构函数中调用虚函数在构造函数和析构函数中调用虚函数 编编译译系系统统对对构构造造函函数数和和析析构构函函数数中中调调用用虚虚函函数数采采用用静静态态联联编编,即即它它们们所所调调用用的的虚虚函函数数是是自自己己的的类类或或基基类类中中定定义义的的函函数数而而不不是是在在任任何何派派生生类类中中重重定定义义

22、的函数。的函数。使用对象调用虚函数也采用静态联编。使用对象调用虚函数也采用静态联编。现在学习的是第20页,共27页l【例【例6.6.18】在构造函数中调用虚函数。在构造函数中调用虚函数。l#includelclassbaselpublic:lbase()coutconstructbaseendl;lvirtualvoidvf()lcoutbase:vf()calledendl;l;lclassson:publicbaselpublic:lson()vf();lvoidg()vf();l;lclassgrandson:publicsonlpublic:lgrandson()coutconstru

23、ctgrandsonendl;lvoidvf()lcoutgrandson:vf()calledn;l;lvoidmain()lgrandsongs;lgs.g();现在学习的是第21页,共27页 6.36.3纯虚函数和抽象类纯虚函数和抽象类6.3.16.3.1纯虚函数的概念纯虚函数的概念 纯纯虚虚函函数数是是一一种种没没有有具具体体实实现现的的特特殊殊的的虚虚函函数数。纯纯虚虚函函数的定义格式如下:数的定义格式如下:virtual类型类型(函数名函数名)()(参数表参数表)=0)=0;现在学习的是第22页,共27页6.3.26.3.2抽象类的概念抽象类的概念1 1抽象类和具体类的概念抽象类和

24、具体类的概念 如如果果一一个个类类至至少少有有一一个个纯纯虚虚函函数数,那那么么就就称称该该类类为抽象类为抽象类。抽抽象象类类的的主主要要作作用用是是为为其其所所组组织织的的继继承承层层次次结结构构提提供供一一个个公公共共的的基基类类,其其它它类类可可以以从从它它这这里里继继承承和和实实现接口,纯虚函数的实现由其具体的派生类来提供。现接口,纯虚函数的实现由其具体的派生类来提供。现在学习的是第23页,共27页2 2对抽象类的规定对抽象类的规定(1)(1)抽抽象象类类只只能能作作为为基基类类来来派派生生新新类类,不不能能建建立立抽抽象象类类的对象。的对象。(2)可可以以声声明明指指向向抽抽象象类类

25、的的指指针针和和引引用用,此此指指针针可可以以指指向向它的公有派生类,进而实现多态性。它的公有派生类,进而实现多态性。现在学习的是第24页,共27页l【例【例6.6.20】计算各类形状的总面积计算各类形状的总面积l#includefloattotal(shape*s,intn)lclassshape/抽象类的定义抽象类的定义lpublic:floatsum=0;lvirtualfloatarea()=0;for(inti=0;iarea();lprotected:returnsum;lfloath,w;lpublic:voidmain()ltriangle(floathh,floatww)lh

26、=hh;w=ww;shape*s4;lfloatarea()s0=newtriangle(3,4);lreturnh*w*0.5;s1=newrectangle(2,4);lclassrectangle:publictriangle/矩形类矩形类s2=newcircle(5);lpublic:s3=newcircle(8);lrectangle(floath,floatw):triangle(h,w)floatsum=total(s,4);lfloatarea()coutsumendl;lreturnh*w;lclasscircle:publicshape/圆类圆类lprivate:lfloa

27、tradius;lpublic:lcircle(floatr)radius=r;lfloatarea()lreturnradius*radius*3.14;现在学习的是第25页,共27页6.46.4虚析构函数虚析构函数如果一个基类的析构函数被说明为虚函数,则它如果一个基类的析构函数被说明为虚函数,则它的派生类的析构函数无论是否使用的派生类的析构函数无论是否使用virtual进行说明,进行说明,都自动成为虚析构函数。都自动成为虚析构函数。虚析构函数的声明语法如下:虚析构函数的声明语法如下:virtual类名类名【例【例6.6.21】虚析构函数的使用虚析构函数的使用现在学习的是第26页,共27页l

28、#includevoidmain()l#includelclassbasebase*px=newderive(5,7,base,derive);lchar*p;deletepx;lpublic:lbase(intsz,char*bptr)lp=newcharsz;lstrcpy(p,bptr);lcoutconstructorbaseendl;lvirtualbase()ldeletep;lcoutdestructorbasen;l;lclassderive:publicbaselchar*pp;lpublic:lderive(intsz1,intsz2,char*bp,char*dptr):base(sz1,bp)lpp=newcharsz2;lstrcpy(pp,dptr);lcoutconstructorderiveendl;lderive()ldeletepp;lcoutdestructorderiven;现在学习的是第27页,共27页

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 大学资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁