C++第6章-虚函数和多态性课件_第1页
C++第6章-虚函数和多态性课件_第2页
C++第6章-虚函数和多态性课件_第3页
C++第6章-虚函数和多态性课件_第4页
C++第6章-虚函数和多态性课件_第5页
已阅读5页,还剩40页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 第六章 虚函数和多态性1目标 理解静态联编和动态联编的含义熟练掌握虚函数的使用掌握虚析构函数的作用掌握抽象类掌握多态性26.1 静态联编和动态联编 36.1 静态联编和动态联编联编是指一个程序模块、代码之间的关联过程,也就是把一个标识符名和一个存储地址联系在一起的过程。按照联编进行阶段的不同,可以分为静态联编和动态联编。46.1 静态联编和动态联编1静态联编所谓静态联编,是指程序之间的匹配、连接工作在编译阶段,即程序运行之前完成,也称为早期联编。 函数重载和运算符重载就属于静态多态性。 所谓函数重载是指同一个函数名可以对应着多个函数的实现。每一种函数的实现对应相同的函数名,但是函数参数的个数

2、不同。5【例6.1】参数个数不同的重载函数实例。#include class MaxClassprivate:int x,y,w,h;public:MaxClass(int,int,int,int);int max(int,int);int max(int,int,int);int max(int,int,int,int);void display();MaxClass:MaxClass(int a,int b,int c,int d)x=a;y=b;w=c;h=d;6int MaxClass:max(int a,int b)x=a;y=b;return xy?x:y;int MaxClass

3、:max(int a,int b,int c)w=c;return max(a,b)w?max(a,b):w;int MaxClass:max(int a,int b,int c,int d)h=d;return max(a,b,c)d?max(a,b,c):h;void MaxClass:display()cout四个数是:x,y,w,hendl;7void main()MaxClass mc(34,67,143,89);cout计算前两个数中的最大数为:“ mc.max(34,67)endl;cout计算前三个数中的最大数为:“ mc.max(34,67,143)endl;cout计算四个

4、数中的最大数为:“ mc.max(34,67,143,89)endl;cout其中,;mc.display ();运行结果:计算前两个数中的最大数为:67计算前三个数中的最大数为:143计算四个数中的最大数为:143其中,四个数是:34,67,143,8986.1 静态联编和动态联编2. 动态联编与静态联编相对应,编译程序在编译阶段不能确定将要调用的函数,只有在程序运行阶段才能确定调用的函数。在编译、连接过程中无法解决的联编问题,要等到程序开始运行之后再来确定该调用的函数,这种联编工作称为动态联编,也称为晚期联编。C+的动态联编是通过虚函数和基类的指针实现的,是一种动态多态。在后面的例题中可以

5、从中了解。96.2 虚函数6.2.1 虚函数的定义6.2.2 虚函数与动态联编6.2.3 虚函数的重载6.2.4 虚析构函数106.2.1 虚函数的定义引入虚函数的目的。虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。116.2.1 虚函数的定义2. 虚函数的定义 虚函数的定义是在基类中进行的 。虚函数的定义语法格式如下:virtual(形参表) 函数体126.2.1 虚函数的定义3. 定义虚函数时,要注意遵循以下规则:1)只有成员函数才能声明为虚函数,因为虚函数仅适用于有继承关系的类对象,所以普通函数不能声明为虚函数。2)虚函数

6、的声明只能出现在类声明中的函数原型声明中,而不能出现在成员的函数体实现上。3)类的静态成员函数不可以定义为虚函数,因为静态成员函数不受限于某个对象。136.2.1 虚函数的定义定义虚函数时,要注意遵循以下规则:4)类的构造函数不可以定义为虚函数。多态是指不同的对象对同一消息有不同的行为特性。虚函数作为运行过程中多态的基础,主要是针对对象的,而构造函数是在对象产生之前运行的,因此,虚构造函数是没有意义的。5)内联函数不能声明为虚函数,因为内联函数不能在运行中动态确定其位置。146.2.2 虚函数与动态联编虚函数是动态联编的基础,如果某个类中的一个成员函数被说明为虚函数,则当使用指针或引用所标识的

7、对象操作这个成员函数时,对该成员函数调用采用动态联编的方式,即在运行时进行关联或束定。虚成员函数是动态联编的,即在运行时是根据对象类型而不是指向该对象的指针或引用类型选择成员函数。动态联编只能通过指针或引用所标识对象来操作虚函数。 15【例6.5】使用虚函数例题。#include #include static int Line=1;class CAnimal /定义基类CAnimalprotected:char *name;public:CAnimal(char *na)name=new charstrlen(na)+1;strcpy(name,na);virtual void displa

8、y()/虚函数声明cout(Line+) : 动物(食草/食肉).endl;16class CHerbivorous:public CAnimal /定义派生类CHerbivorous public:CHerbivorous(char *na):CAnimal(na)void display()/重新定义虚函数cout(Line+) : 食草动物 : nameendl;/定义派生类CCarnivore(食肉动物)class CCarnivore:public CAnimalpublic:CCarnivore(char *na):CAnimal(na)void display()/重新定义虚函数

9、cout(Line+) : 食肉动物 : namedisplay();ptrAni=&herb;ptrAni-display();(CHerbivorous *) ptrAni)-display();ptrAni=&carn;ptrAni-display();(CCarnivore *)ptrAni)-display();herb.display();carn.display();运行结果:(1) : 动物(食草/食肉).(2) : 食草动物 : 羚羊(3) : 食草动物 : 羚羊(4) : 食肉动物 : 老虎(5) : 食肉动物 : 老虎(6) : 食草动物 : 羚羊(7) : 食肉动物 :

10、 老虎186.2.3 虚函数的重载1. 虚函数与重载的关系一般的函数重载,只要函数名相同,函数的所带参数的个数、类型或次序不同。当重载一个虚函数时,也就是说在派生类中重新定义此虚函数时,要求函数名、返回类型、参数个数、参数类型以及参数的顺序都与基类中的原型完全相同,不能有任何的不同。【例6.7】虚函数重载。 19#include #include class personprotected:char *name;public:person(char *n) name=new charstrlen(n)+1;strcpy(name,n);person() delete name; virtual

11、 void printInfo()/基类中的函数 cout姓名 : namen;20class worker: public personprivate: char *type;public:worker(char *na,char *t=Steel Worker):person(na)type=new charstrlen(t)+1;strcpy(type,t);worker() delete type; void printInfo ()/在派生类worker中重新定义 coutname,; couttypeendl;21class teacher: public personprivat

12、e: char *subject;public:teacher(char *na,char *s):person(na)subject=new charstrlen(s)+1;strcpy(subject,s);teacher() delete subject; void printInfo ()/在派生类teacher中重新定义 coutname,; coutsubject教师printInfo(); p=&t; p-printInfo();运行结果:张晓强,园林工人李文卓,生命科学教师236.2.3 虚函数的重载2. 多继承中的虚函数 【例6.8】多继承中使用虚函数例题。#include

13、class base1/定义基类base1public:virtual void display()/函数定义为虚函数cout基类base1.endl;24class base2/定义基类base2public:void display()/函数为一般成员函数cout基类base2.endl;class derive:public base1,public base2public:void display()cout派生类derive公有继承base1和base2.display();ptr1=&obj3; ptr1-display(); /动态联编,ptr1类型为derive类型ptr2=&

14、obj2;ptr2-display();ptr2=&obj3; ptr2-display(); /静态联编,ptr1类型为base2类型运行结果:基类base1.派生类derive公有继承base1和base2.基类base2.基类base2.266.2.4 虚析构函数在析构函数前面冠以关键字virtual进行说明,则称该析构函数为虚析构函数。虚析构函数的声明语法格式如下: virtual 类名()例如:class examplepublic: virtual example(); ;276.3 纯虚函数和抽象类6.3.1 纯虚函数6.3.2 抽象类286.3.1 纯虚函数一些类表示没有具体意

15、义的抽象概念,它不能为其虚函数提供具体的定义,因此可以定义为纯虚函数。纯虚函数是一个在基类中说明的虚函数,它在该基类中只有一个函数声明,并没有具体函数功能的实现。纯虚函数的声明形式如下: virtual(参数表)=0;不能创建含有一个或多个纯虚函数的类对象,纯虚函数不可以直接调用,也不可以被继承。 296.3.2 抽象类包含一个或多个纯虚函数的类称为抽象类。由于抽象类中的纯虚函数没有具体的函数实现,因此不能定义抽象类的对象。抽象类只能作为基类被子类继承,其纯虚函数的实现由派生类给出。抽象类的重要用处是提供一个接口,而不揭示任何实现的细节。抽象类不能用作参数类型、函数返回类型或强制类型转换。但是

16、,可以声明抽象类的指针和引用。 30【例614】使用抽象指针。#include class CPoint /抽象基类CPoint声明protected:long x,y;public:CPoint(int xx=0,int yy=0)x=xx;y=yy;virtual void display()=0; /纯虚函数成员; 31class CRectangle:public CPoint/派生类Rectangle声明private:double width,height;public:CRectangle(long x,long y,double w,double h):CPoint(x,y)w

17、idth=w;height=h;void display()/虚成员函数cout矩形endl;cout位置 : ( x , y )endl;cout长 = width , 宽 = heightendl;32class CTriangle:public CPoint/派生类CTriangle声明private:double a,b,c;public:CTriangle(long x,long y,double a1,double b1,double c1):CPoint(x,y) a=a1; b=b1; c=c1;void display()/虚成员函数cout三角形endl;cout位置 :

18、( x , y )endl;cout三边长 : a , b , cdisplay();coutdisplay();运行结果:矩形位置 : ( 10 , 10 )长 = 120 , 宽 = 60-三角形位置 : ( 50 , 50 )三边长 : 345 , 456 , 567346.4 多态356.4 多态6.4.1 多态的含义6.4.2 多态的应用366.4.1 多态的含义所谓多态性是指同一个接口被不同的对象操作产生不同的响应。面向对象的多态性从实现的角度来讲,可以分为静态多态性和动态多态性两种。静态多态性是在编译的过程中确定同名操作的具体操作对象的,而动态多态性则是在程序运行过程中动态地确定

19、操作所针对的具体对象的。所谓消息,是指对类的成员函数的调用。不同的方法是指不同的实现,也就是调用了不同的函数。 376.4.1 多态的含义动态多态是通过虚函数来实现的,虚函数的使用本质是将派生类类型的指针赋给基类类型的指针,虚函数被调用时会自动判断调用对象的类型,从而做出相应的响应。【例616】多态应用举例。 #include const double Pi=3.141593;class Shapespublic: virtual void draw()=0;/基类中的纯虚函数 virtual double area()=0; /基类中的纯虚函数;38class Circle: public

20、Shapesprivate: double radius;public: Circle(double r) radius=r; void draw()/在派生类中实现coutDraw circle.endl;coutRadius = radiusendl;double area()/在派生类中实现return Pi*radius*radius;39class Square: public Shapesprivate: double length;public:Square(double len) length=len; void draw()/在派生类中实现coutDraw square.en

21、dl;coutLength = lengthdraw(); cout Circle area : area()endl; coutdraw(); cout Square area : area()endl;运行结果:Draw circle.Radius = 10Circle area : 314.159-Draw square.Length = 12Square area : 144416.4.2 多态的应用【例618】设计动物类Animal,提供纯虚函数food( )显示不同动物的食物;派生类Elephant类表示大象类,具体实现成员函数food( )显示Elephant的食物,派生类Lion类表示狮子类,具体实现成员函数food( )显示Lion的食物。定义普通函数ShowFood( )

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论