C++程序设计基础第12章虚函数与多态性课件.pptx

上传人(卖家):晟晟文业 文档编号:4984869 上传时间:2023-01-30 格式:PPTX 页数:32 大小:352.28KB
下载 相关 举报
C++程序设计基础第12章虚函数与多态性课件.pptx_第1页
第1页 / 共32页
C++程序设计基础第12章虚函数与多态性课件.pptx_第2页
第2页 / 共32页
C++程序设计基础第12章虚函数与多态性课件.pptx_第3页
第3页 / 共32页
C++程序设计基础第12章虚函数与多态性课件.pptx_第4页
第4页 / 共32页
C++程序设计基础第12章虚函数与多态性课件.pptx_第5页
第5页 / 共32页
点击查看更多>>
资源描述

1、第第12章章 虚函数与多态性虚函数与多态性主讲:李政伟主讲:李政伟2第第12章章 虚函数与多态性虚函数与多态性12.1 多态性的概念多态性的概念12.2 虚函数的定义虚函数的定义12.3 抽象类抽象类12.4 实例研究实例研究3多态性多态性多态一词最初来源于希腊语多态一词最初来源于希腊语Polumorphos,含义是具,含义是具有多种形式或形态的情形。有多种形式或形态的情形。多态性多态性:发出同样的:发出同样的消息消息被不同类型的对象接收时会被不同类型的对象接收时会导致完全不同的行为。导致完全不同的行为。多态性多态性:父类型具有:父类型具有“引用由它派生的任何子类型引用由它派生的任何子类型”的

2、能力。的能力。多态的实现途径多态的实现途径12.1 多态性多态性(polymorphism)的概念的概念静态多态静态多态动态多态动态多态4函数重载函数重载:在同一作用域内的多个函数采用相:在同一作用域内的多个函数采用相同名字,只要使用不同类型、不同数目的参数。同名字,只要使用不同类型、不同数目的参数。作为重载函数作为重载函数:(1)至少在参数个数、参数类型上有所不同。)至少在参数个数、参数类型上有所不同。(2)使用缺省函数参数要注意二义性。)使用缺省函数参数要注意二义性。如:如:void print(int a,int b);void print(int a,int b,int c=50);p

3、rint(10,100);12.1 多态性多态性(polymorphism)的概念的概念512.1 多态性多态性(polymorphism)的概念的概念运算符重载运算符重载:对已有的运算符赋予多重含义。:对已有的运算符赋予多重含义。必要性必要性&C+中预定义运算符其运算对象只能是中预定义运算符其运算对象只能是标标准数据类型准数据类型,而不适用于,而不适用于用户自定义类型用户自定义类型(如类)。(如类)。实现机制实现机制&将指定的运算表达式转化为对将指定的运算表达式转化为对运算符函数运算符函数的调用,运算对象转化为运算符函数的的调用,运算对象转化为运算符函数的实参实参。6分类分类系统实现的角度系

4、统实现的角度&静态多态性静态多态性:在:在编译时编译时系统就能决定调用系统就能决定调用哪个函数,又称哪个函数,又称编译时的多态性编译时的多态性。函数重载、运算符重载函数重载、运算符重载&动态多态性动态多态性:在:在运行过程中运行过程中才动态确定操才动态确定操作所针对的对象。又称作所针对的对象。又称运行时多态运行时多态。虚函数虚函数(virtual function)12.1 多态性多态性(polymorphism)的概念的概念7class Point public:Point(double i,double j)x=i;y=j;double Area()const return 0.0;pri

5、vate:double x,y;class Rectangle:public Point public:Rectangle(double i,double j,double k,double l);double Area()const return w*h;private:double w,h;例例12.1 非虚函数举例非虚函数举例8Rectangle:Rectangle(double i,double j,double k,double l):Point(i,j)w=k;h=l;void fun(Point&Pref)coutArea=Pref.Area()endl;void main()R

6、ectangle rec(3.0,6.0,15.0,20.0);fun(rec);例例12.1非虚函数举例非虚函数举例注意事项注意事项派生类对象指针使用时应注意的问题:派生类对象指针使用时应注意的问题:(1)声明为指向基类对象的指针可以指向它的公有派)声明为指向基类对象的指针可以指向它的公有派生类的对象,但不允许指向它的私有派生类的对象。生类的对象,但不允许指向它的私有派生类的对象。(2)允许声明为指向基类对象的指针指向它的公有派)允许声明为指向基类对象的指针指向它的公有派生类的对象,但不允许将一个声明为指向派生类对象生类的对象,但不允许将一个声明为指向派生类对象的指针指向基类的对象。的指针指

7、向基类的对象。(3)声明为指向基类对象的指针,当其指向它的公有)声明为指向基类对象的指针,当其指向它的公有派生类的对象时,只能直接访问派生类中从基类继承派生类的对象时,只能直接访问派生类中从基类继承下来的成员,不能直接访问公有派生类中定义的成员。下来的成员,不能直接访问公有派生类中定义的成员。要想访问其公有派生类中的成员,可将基类指针用显要想访问其公有派生类中的成员,可将基类指针用显式类型转换方式转换为派生类指针。式类型转换方式转换为派生类指针。1012.3 虚函数虚函数12.3.1 虚函数的作用虚函数的作用同一类中同一类中不能不能定义定义名字名字,参数个数参数个数和和类型类型都相都相同的函数

8、,不能同的函数,不能“重复定义重复定义”。不同层次中不同层次中可以可以出现出现名字名字、参数个数参数个数和和类型类型都都相同而功能不同的函数。系统按照相同而功能不同的函数。系统按照同名覆盖同名覆盖的的原则决定调用对象。原则决定调用对象。rc1.area()/派生类派生类Rectangle的成员函数的成员函数。rc1.Point:area()/基类基类Point的成员函数的成员函数Pref.area()11虚函数的声明形式虚函数的声明形式virtual ()函数体函数体&成员成员函数,函数,非非static成员函数成员函数&有继承性,基类中定义了虚函数,派生类中有继承性,基类中定义了虚函数,派生

9、类中,同原型函数都自动为虚函数。,同原型函数都自动为虚函数。&作用作用:。12.3 虚函数虚函数12class Apublic:virtual void display()cout“A:display();class B:public A public:void display()/自动成为虚函数自动成为虚函数 cout“B:display();class C:public B public:void display()/自动成为虚函数自动成为虚函数 cout“C:display()display();void main()A a1,*p;B b1;C c1;p=&a1;fun(p);p=&b

10、1;fun(p);p=&c1;fun(p);13虚函数的使用方法虚函数的使用方法(1)基类中用基类中用virtual声明其为声明其为虚函数虚函数(2)要求要求函数名函数名、返回类型返回类型、参数个数参数个数和和类类型型全部与基类的虚函数相同,根据需要重新全部与基类的虚函数相同,根据需要重新定义函数体。定义函数体。(3)定义一个定义一个指向基类对象的指针变量指向基类对象的指针变量,使,使它指向同一类族中要调用该函数的对象。它指向同一类族中要调用该函数的对象。(4)通过该指针变量调用此虚函数通过该指针变量调用此虚函数,调用的是,调用的是指针变量指向的对象所属类的同名函数。指针变量指向的对象所属类的

11、同名函数。例例12.2 基类与派生类中有同名函数基类与派生类中有同名函数14函数重载函数重载可用于普通函数和类的成员函数;可用于普通函数和类的成员函数;虚函数虚函数只能用于类的成员函数。只能用于类的成员函数。函数重载函数重载可用于构造函数;可用于构造函数;虚函数虚函数不可以。不可以。重载成员函数重载成员函数必须属于同一个类,为横向;必须属于同一个类,为横向;虚函数虚函数是同一类族中基类和派生类的是同一类族中基类和派生类的同同原型原型函数,为纵向。函数,为纵向。函数重载函数重载要求函数名字相同,但参数个数或类型不要求函数名字相同,但参数个数或类型不同;同;虚函数虚函数要求同一类族所有虚函数的名字

12、、参数要求同一类族所有虚函数的名字、参数类型、个数完全相同。类型、个数完全相同。函数重载函数重载在编译时确定;在编译时确定;虚函数虚函数在程序运行时确定。在程序运行时确定。函数重载函数重载 PK 虚函数虚函数12.2.3 虚函数的限制虚函数的限制使用虚函数时应注意如下问题:使用虚函数时应注意如下问题:(1)虚函数声明只能出现在类声明的函数原型的声明)虚函数声明只能出现在类声明的函数原型的声明中,不能出现在函数体实现中,同时基类中只有保护中,不能出现在函数体实现中,同时基类中只有保护成员或公有成员才能被声明为虚函数。成员或公有成员才能被声明为虚函数。(2)派生类中重新定义虚函数时,关键字)派生类

13、中重新定义虚函数时,关键字virtual可以写可以写也可不写,为避免引起混乱,应写上该关键字。也可不写,为避免引起混乱,应写上该关键字。(3)动态联编只能通过成员函数来调用或通过指针、)动态联编只能通过成员函数来调用或通过指针、引用来访问虚函数,如果用对象名的形式来访问虚函引用来访问虚函数,如果用对象名的形式来访问虚函数,将采用静态联编。数,将采用静态联编。(4)构造函数不能声明为虚函数,析构函数可以声明)构造函数不能声明为虚函数,析构函数可以声明为虚函数为虚函数例例12.3 基类中有非虚析构函数时的情况基类中有非虚析构函数时的情况class Point /基类基类Point类类 public

14、:Point()Point()coutexecuting Point destructorendl;class Circle:public Point /派生类派生类Circle类类public:Circle()Circle()coutexecuting Circle destructorendl;private:int radius;int main()Point*p=new Circle;delete p;executing Point destructor1712.3.4 虚析构函数虚析构函数用用new运算符建立对象,且定义了指向基运算符建立对象,且定义了指向基类的指针变量。用带指针参数

15、的类的指针变量。用带指针参数的delete运运算符撤销对象时:算符撤销对象时:只执行只执行基类基类析构函析构函数,而不执行派生类的析构函数数,而不执行派生类的析构函数。18virtual Point()coutexecuting Point destructorendl;executing Circle destructorexecuting Point destructor例例12.3 基类中有非虚析构函数时的情况基类中有非虚析构函数时的情况基类的析构函数为虚函数时,该基类的所基类的析构函数为虚函数时,该基类的所有派生类的有派生类的析构函数析构函数都都自动成为虚函数自动成为虚函数,即使两者的

16、名字不同。即使两者的名字不同。推荐推荐:基类析构函数声明为虚函数基类析构函数声明为虚函数。1912.4 纯纯虚函数与抽象类虚函数与抽象类12.4.1 纯虚函数纯虚函数基类中成员函数设为虚函数,基类中成员函数设为虚函数,一般并不是基类一般并不是基类本身的要求本身的要求,而是考虑到派生类的需要。,而是考虑到派生类的需要。基类基类Point没有求面积的没有求面积的Area函数,函数,“点点”没有没有面积,基类本身不需要这个函数。面积,基类本身不需要这个函数。直接派生类直接派生类Circle和间接派生类和间接派生类Rectangle中都中都需要需要Area函数,且功能不同。函数,且功能不同。2012.

17、4.1 纯虚函数纯虚函数virtual float area()const return 0;/虚函数虚函数virtual float area()const=0;/纯虚函数纯虚函数纯虚函数纯虚函数(pure virtual function):在声明虚函数:在声明虚函数时被时被“初始化初始化”为为0的函数。的函数。纯虚函数的声明格式:纯虚函数的声明格式:virtual 函数类型函数类型 函数名函数名(参数表列参数表列)=0;注注:无函数体;无函数体;“=0”不表示返回值为不表示返回值为0,只用,只用来告知是纯虚函数来告知是纯虚函数;以分号结束。以分号结束。21只有函数名字而不具备函数的功能,

18、不能被只有函数名字而不具备函数的功能,不能被调用。只是通知编译系统调用。只是通知编译系统:这里声明一个虚这里声明一个虚函数,留待派生类中定义函数,留待派生类中定义。作用作用:基类中为其保留了函数名字,以便派:基类中为其保留了函数名字,以便派生类根据需要对它进行定义。生类根据需要对它进行定义。若基类声明了纯虚函数,而派生类没有定义,若基类声明了纯虚函数,而派生类没有定义,则该虚函数在派生类中仍然为纯虚函数。则该虚函数在派生类中仍然为纯虚函数。12.4.1 纯虚函数纯虚函数2212.4.2 抽象类抽象类(abstract class)定义定义1:不能用来定义对象不能用来定义对象而只作为基类的类。而

19、只作为基类的类。定义定义2:带有带有纯虚函数纯虚函数的类。的类。作用作用若在派生类中对抽象类的所有纯虚函数进行了定义,若在派生类中对抽象类的所有纯虚函数进行了定义,派生类就成了派生类就成了具体类具体类。若在派生类中没有对所有纯虚若在派生类中没有对所有纯虚函数进行定义,则此派生类仍为函数进行定义,则此派生类仍为抽象类抽象类。23例例12.4 虚函数和抽象基类的应用虚函数和抽象基类的应用例例12.4 虚函数和抽象基类的应用。虚函数和抽象基类的应用。对对Point为基类的点为基类的点圆圆圆柱体类的层次结圆柱体类的层次结构进行改写,要求使用虚函数和抽象基类。构进行改写,要求使用虚函数和抽象基类。顶层是

20、抽象基类顶层是抽象基类Shape(形状形状)。Point(点点),Circle(圆圆),Cylinder(圆柱体圆柱体)都是都是Shape类的类的直接派生类和间接派生类。直接派生类和间接派生类。24第第(1)部分部分class Shape/抽象基类抽象基类Shapepublic:virtual float area()const return 0.0;virtual float volume()const return 0.0;virtual void shapeName()const=0;25第第(2)部分部分class Point:public Shape/Shape的公用派生类的公用派生

21、类public:Point(float=0,float=0);void setPoint(float,float);float getX()const return x;float getY()const return y;virtual void shapeName()const coutPoint:;friend ostream&operator(ostream&,const Point&);protected:float x,y;26class Circle:public Point /Circle类类public:Circle(float x=0,float y=0,float r=0

22、);void setRadius(float);float getRadius()const;virtual float area()const;virtual void shapeName()const coutCircle:;friend ostream&operator(ostream&,const Circle&);protected:float radius;第第(3)部分部分27Circle:Circle(float a,float b,float r):Point(a,b),radius(r)void Circle:setRadius(float r):radius(r)floa

23、t Circle:getRadius()const return radius;float Circle:area()const return 3.14159*radius*radius;ostream&operator(ostream&output,const Circle&c)outputc.x,c.y,r=c.radius;return output;第第(3)部分部分28第第(4)部分部分class Cylinder:public Circle/Cylinder类类public:Cylinder(float x=0,float y=0,float r=0,float h=0);void

24、 setHeight(float);virtual float area()const;virtual float volume()const;virtual void shapeName()const coutCylinder:;friend ostream&operator(ostream&,const Cylinder&);protected:float height;29Cylinder:Cylinder(float a,float b,float r,float h):Circle(a,b,r),height(h)float Cylinder:area()const return 2

25、*Circle:area()+2*3.14159*radius*height;float Cylinder:volume()const return Circle:area()*height;ostream&operator(ostream&output,const Cylinder&cy)outputcy.x,cy.y,r=cy.radius,h=cy.height;return output;第第(4)部分部分30int main()Point point(3.2,4.5);Circle circle(2.4,1.2,5.6);Cylinder cylinder(3.5,6.4,5.2,1

26、0.5);point.shapeName();coutpointendl;circle.shapeName();coutcircleendl;cylinder.shapeName();coutcylinderendlshapeName();coutx=point.getX(),y=point.getY()narea=area()nvolume=volume()shapeName();/动态关联动态关联 coutx=circle.getX(),y=circle.getY()narea=area()nvolume=volume()shapeName();/动态关联动态关联coutx=cylinder.getX(),y=cylinder.getY()narea=area()nvolume=volume()nn;return 0;第第(5)部分部分32Thank YouThe End of Ch.12.

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 办公、行业 > 各类PPT课件(模板)
版权提示 | 免责声明

1,本文(C++程序设计基础第12章虚函数与多态性课件.pptx)为本站会员(晟晟文业)主动上传,163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
2,用户下载本文档,所消耗的文币(积分)将全额增加到上传者的账号。
3, 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(发送邮件至3464097650@qq.com或直接QQ联系客服),我们立即给予删除!


侵权处理QQ:3464097650--上传资料QQ:3464097650

【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。


163文库-Www.163Wenku.Com |网站地图|