多态类与抽象类.ppt
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《多态类与抽象类.ppt》由会员分享,可在线阅读,更多相关《多态类与抽象类.ppt(32页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第10章多态类与抽象类10.1虚函数与多态类在在一一个个类类中中用用关关键键字字virtual 说说明明的的成成员员函函数数称称为为虚虚函函数数。定定义义了了虚虚函函数的类称为多态类。纯虚函数原型语句格式如下数的类称为多态类。纯虚函数原型语句格式如下:virtual 类型类型 函数名(参数表);函数名(参数表);在在基基类类中中某某个个成成员员函函数数被被声声明明为为虚虚函函数数后后,这这个个成成员员函函数数通通常常要要在在派派生生类类中中被被重重新新定定义义。定定义义一一个个虚虚函函数数的的目目的的是是为为了了在在程程序序运运行行时时自自动动选选择择各各派派生生类类中中的的重重定定义义版版本
2、本,所所以以一一个个多多态态的的基基类类一一定定要要定定义义一一个个以以上上的派生类才有意义。的派生类才有意义。在在派派生生类类中中重重新新定定义义虚虚函函数数时时,其其函函数数原原型型(包包括括返返回回值值类类型型、函函数数名名、参参数数个个数数、参参数数类类型型及及顺顺序序)必必须须与与基基类类中中的的原原型型完完全全相相同同。否否则则编译时会出错或被当作函数重载处理。编译时会出错或被当作函数重载处理。一一个个指指向向基基类类的的指指针针可可以以指指向向它它的的公公有有继继承承的的派派生生类类。定定义义虚虚函函数数的的目目的的就就是是想想统统一一用用一一个个基基类类对对象象指指针针去去访访
3、问问不不同同派派生生类类中中虚虚函函数数的的重重定定义代码。义代码。1 虚函数的概念和定义虚函数的概念和定义#includeclass Poultry public:virtual void can_fly()/虚函数定义虚函数定义 coutYes!I can.endl;class Cock:public Poultrypublic:void can_fly()/虚函数重定义虚函数重定义 coutYes!I can.But I cant fly high.endl;class Duck:public Poultrypublic:void can_fly()/虚函数重定义虚函数重定义 coutN
4、o!I cant.But I can swimming.can_fly();ptr=&aCock;ptr-can_fly();ptr=&aDuck;ptr-can_fly();aCock.can_fly();aDuck.can_fly();例10.1多态类与虚函数访问程序输出:程序输出:Yes!I can.Yes!I can.But I cant fly high.No!I cant.But I can swimming.Yes!I can.But I cant fly high.No!I cant.But I can swimming.以以上上运运行行结结果果表表明明,只只要要把把派派生生类
5、类对对象象的的地地址址传传递递给给基基类类指指针针,就就可可以以直直接接使使用用基基类类指指针针调调用用派派生生类类中中虚虚函函数数的的重重定定义义版版本本,与与通通过过派派生生类类对对象象名名调调用用该该函函数数有有相相同同的的执执行行结结果果。虚虚函函数数的的引引入入,使使类类似似ptr-can_fly();这这样样的的函函数数调调用用语语句句有有了了动动态态选选择择执执行行代代码码的的智智能能。这这一一点点是是通通过过动动态态绑绑定定技术实现的。技术实现的。2动态绑定及其实现技术所所谓谓绑绑定定(binding)是是指指编编译译程程序序将将源源程程序序中中的的函函数数调调用用语语句句与与
6、该该函函数数的的执执行行代代码码联联系系在在一一起起的的过过程程。换换句句话话说说,绑绑定定就就是是让让函函数数调调用用语语句句找找到到它它要要执执行行的的代代码码。在在非非面面向向对对象象程程序序设设计计语语言言中中,绑绑定定过过程程都都是是静静态态的的,也也就就是是说说,所所有有的的绑绑定定都都是是在在编编译译期期完完成成的的。静静态态绑绑定定的的函函数数调调用用语语句句有有唯唯一一确确定的语义,不可能具有多态性。定的语义,不可能具有多态性。动态绑定是通过虚函数表实现的。动态绑定是通过虚函数表实现的。对对于于含含有有虚虚函函数数的的多多态态类类,编编译译器器为为每每个个对对象象生生成成一一
7、个个虚虚表表指指针针。即即在在每每个个对对象象的的内内存存映映像像中中增增加加了了一一个个_vfptr指指针针,它它指指向向一一个个虚虚函函数数表表vtable。在在基基类类的的虚虚函函数数表表中中列列出出基基类类所所有有虚虚函函数数的的入入口口地地址址,在在派派生生类类的的虚虚函函数数表表中中列列出出派派生生类类的的所有虚函数的入口地址。所有虚函数的入口地址。例10.2非多态类与重定义函数的调用#includeclass Memberpublic:void answer()coutI am a member.n;class Teacher:public Memberpublic:void a
8、nswer()coutI am a teacher.n;class Student:public Memberpublic:void answer()coutanswer();Who=&aTeacher;Who-answer();Who=&aStudent;Who-answer();这这个个程程序序将将输输出出以以下下三三行行相相同同的的结结果果,没没有有出出现现程程序序设设计计者者期待的多态性!期待的多态性!I am a member.I am a member.I am a member.这这是是由由于于函函数数answer()不不是是一一个个虚虚函函数数,所所有有对对它它的的调调用用语语
9、句句都都是是静静态态绑绑定定的的,即即三三个个Who-answer();调调用用执执行行的的是同样的代码。是同样的代码。例10.3多态点类定义及测试#includeclass Pointprotected:int x,y;public:Point(int a,int b)x=a;y=b;virtual void print()cout(“x”,”y”)”endl;virtual void forward(int d);class Point_3d:public Point int z;public:Point_3d(int a,int b,int c):Point(a,b)z=c;virtua
10、l void print()cout“x”,”y”,”z”print();ptr=&d2;ptr-print();ptr-forward(5);ptr=&d1;ptr-print();ptr=&d2;ptr-print();程序运行结果程序运行结果(2,4)1,3,5(2,4)6,8,10有无虚函数时对象内存映象对比Point对象d1(无虚函数)xyPoint_3d对象d2基类子对象xyzPoint对象d1(有虚函数)_vfptr xyPoint_3d对象d2基类子对象_vfptr xyzPoint:print()Point:forward()Point_3d:print()Point_3d:
11、forward()0202虚函数动态绑定的调用步骤 首先为多态类的基类声明一个指针变量,首先为多态类的基类声明一个指针变量,然后让这个指针变量指向此多态类继承树中某然后让这个指针变量指向此多态类继承树中某一个类的对象。由于基类指针指向对象内存映一个类的对象。由于基类指针指向对象内存映像的首地址,它直接访问的是该对象的虚表指像的首地址,它直接访问的是该对象的虚表指针,下一步由具体对象的虚表指针就可以访问针,下一步由具体对象的虚表指针就可以访问到该对象所在的类中为虚函数定义的那一份代到该对象所在的类中为虚函数定义的那一份代码。码。虚函数调用的汇编语言代码说说明明:1.函函数数forward()的的
12、参参数数表表中中实实际际上上有有两两个个参参数数(*this,int),C+函函数数调调用用时时参参数数按按从从右右到到左左的的次次序序入入栈栈。this 指指针针指指向向obj的的首首地地址址。由由汇汇编编代代码码可可以以看看到到,this指针是用指针是用si寄存器实现的。寄存器实现的。2.mov bx,word ptrsi 将将虚虚函函数数表地址表地址(_vfptr)装入寄存器装入寄存器bx3.call word ptrbx+2 调调用用forward()函函数数,forward()函函数数在在虚虚函函数数表中地址偏移量为表中地址偏移量为24.调调用用返返回回后后,add sp,4 将将参
13、参数数清栈。清栈。设函数设函数func()定义如下:定义如下:func(Point&obj)obj.forward(5);语句语句obj.forward(5)编译产生的汇编代码:编译产生的汇编代码:push 5push simov bx,word ptrsicall word ptrbx+2add sp,4虚函数与消息调用动动态态绑绑定定的的目目的的是是为为程程序序引引入入消消息息机机制制。程程序序用用指指针针形形式式实实现的虚函数调用就是消息调用。现的虚函数调用就是消息调用。引引发发消消息息调调用用的的人人机机交交互互操操作作或或某某一一对对象象的的状状态态改改变变统统称称消消息事件。息事件
14、。不不同同的的消消息息由由消消息息名名区区分分。消消息息调调用用可可以以携携带带多多个个不不同同的的参参数数,其其中中第第一一个个(隐隐含含)参参数数是是消消息息指指针针,即即定定义义该该消消息息的的基基类类指指针针,消消息息调调用用时时该该指指针针指指向向接接收收消消息息的的对对象象(即即以以接接收收消消息息的的对对象象的的内内存存映映像像地地址址为为实实参参)。不不同同的的消消息息接接收收者者对对同同一一消消息息调调用用执执行行不不同同的的代代码码,做做出出不不同同的的响响应应。例例如如在在WINDOWS系系统统中中,鼠鼠标标单单击击事事件件引引发发一一条条消消息息调调用用,接接收收消消息
15、息的的可可能能是是窗窗体体,某某个个按按钮钮或或者者某某一一菜菜单单项项,系系统统将将根根据据鼠标击中的位置分别做出相应的反应。鼠标击中的位置分别做出相应的反应。虚函数应用举例1“一个接口,多种实现一个接口,多种实现”前前面面曾曾经经提提到到,类类的的公公开开成成员员函函数数可可以以看看作作类类封封装装体体向向外外界界提提供供的的接接口口,虚虚函函数数的的引引入入使使得得基基类类和和它它的的派派生生类类有有了了一一个个共共同同的的接接口口。这这种种“一一个个接接口口,多多种种实实现现”概概念念所所体体现现的的动动态态多多分分支支选选择择机机制制为为面面向向对对象象系系统统提提供供了了控控制制更
16、更大大复复杂杂性性的的能能力力。在在下下面面例例10.4的的程程序序中中,类类Circle、Triangle、Rectangle具具有有相相同同的的接口接口area(),但有各自不同的实现方法。但有各自不同的实现方法。例10.4利用虚函数求平面图形的面积1#includeconst double PI=3.1416;class Figureprotected:double a,b;public:Figure(double x,double y=0)a=x;b=y;virtual void area()coutCant define area for an abstraction figuree
17、ndl;class Circle:public Figure public:Circle(double x):Figure(x)virtual void area()coutCircle with radius a has an area of PI*a*aendl;例10.4利用虚函数求平面图形的面积2class Triangle:public Figure public:Triangle(double x,double y):Figure(x,y)virtual void area()coutTriangle with base a and high b has an area of 0.
18、5*a*bendl;class Rectangle:public Figure public:Rectangle(double x,double y):Figure(x,y)virtual void area()coutRectangle with lenth a and width b has an area of a*barea();p=&obj_t;p-area();p=&obj_r;p-area();程序运行结果:程序运行结果:Circle with radius 10 has an area of 314.16Triangle with base 10 and high 5 has
19、an area of 25Rectangle with lenth 12 and width 6 has an area of 72虚函数应用举例22 多态数据结构多态数据结构堆堆栈栈、队队列列、链链表表等等数数据据结结构构中中的的数数据据通通常常都都是是单单一一类类型型的的。利利用用类类的的多多态态性性,可可以以构构造造异异质质的的数数据据结结构构,即即数数据据单单元元由由不不同同类类的的对对象象组组成成的的结结构构。例例如如,一一个个可可以以压压入入不不同同(长长度度)对对象象的的堆堆栈栈。多多态态数数据据结结构构是是面面向向对对象象的的数数据据库库、多多媒媒体体数数据据库库的的数数据据存
20、存储储基基础础。例例10.5的的程程序序中中定定义义了了基基类类Phone和和它它三三个个派派生生类类BP_user、Fax_user、Mobile_user,它它们们分分别别代代表表拥拥有有不不同同通通信信设设备备的的人人员员,这这几几个个类类具具有有两两个个共共同同的的接接口口:insert()和和print()。基基类类和和派派生生类类各各自自的的实实现现代代码码能能正正确确地地创创建建和和打打印印自自己己的的对对象象。能能够够使使用用相相同同的的对对象象指指针针是是这这几几个个类类的的对对象象的的“异异”中中之之“同同”,正正是是这这种种共共性性,使使他们能够进入同一个数据结构他们能够
21、进入同一个数据结构链表中。链表中。例10.5多态(异质)链表实现。1#include#includeclass Phone friend class List;protected:char name20;char cityNo5;char phoneNo10;static Phone*ptr;Phone*next;public:Phone(char*,char*,char*);virtual void insert();virtual void print();class BP_user:public Phone char server10;char call10;public:BP_user
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 多态类 抽象
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内