《C++程序设计》课件第5章.ppt
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《《C++程序设计》课件第5章.ppt》由用户(momomo)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+程序设计 C+ 程序设计 课件
- 资源描述:
-
1、1C+程序设计第第5 5章章 多态性与虚函数多态性与虚函数2第第5章章 多态性与虚函数多态性与虚函数 什么是多态性什么是多态性 向上类型转换向上类型转换 功能早绑定和晚绑定功能早绑定和晚绑定 实现功能晚绑定实现功能晚绑定虚函数虚函数 纯虚函数和抽象类纯虚函数和抽象类 学生信息管理系统中的多态性学生信息管理系统中的多态性本章学习要点本章学习要点3第第5章章 多态性与虚函数多态性与虚函数多态性是指用一个名字定义不同的函数,多态性是指用一个名字定义不同的函数,这些函数执行不同但又类似的操作,从而这些函数执行不同但又类似的操作,从而可以使用相同的调用方式来调用这些具有可以使用相同的调用方式来调用这些具
2、有不同功能的同名函数。不同功能的同名函数。实现实现“一个接口,多种方法一个接口,多种方法”45.1 什么是多态性什么是多态性多态性可以分为多态性可以分为4类:类:参数多态参数多态包含多态包含多态重载多态重载多态强制多态。强制多态。55.1 什么是多态性什么是多态性 参数多态如函数模板和类模板。参数多态如函数模板和类模板。由函数模板实例化的各个函数都具有相由函数模板实例化的各个函数都具有相同的操作,而这些函数的参数类型却各不同的操作,而这些函数的参数类型却各不相同。同样地,由类模板实例化的各个类相同。同样地,由类模板实例化的各个类都具有相同的操作,而操作对象的类型是都具有相同的操作,而操作对象的
3、类型是各不相同的。各不相同的。65.1 什么是多态性什么是多态性包含多态是研究类族中定义于不同类中包含多态是研究类族中定义于不同类中的同名成员函数的多态行为,主要是通过的同名成员函数的多态行为,主要是通过虚函数来实现的。虚函数来实现的。75.1 什么是多态性什么是多态性重载多态如函数重载、运算符重载等。重载多态如函数重载、运算符重载等。前面我们学习过的普通函数及类的成员函前面我们学习过的普通函数及类的成员函数的重载都属于重载多态。数的重载都属于重载多态。85.1 什么是多态性什么是多态性强制多态是指将一个变元的类型加以变强制多态是指将一个变元的类型加以变化,以符合一个函数(或操作)的要求,化,
4、以符合一个函数(或操作)的要求,例如加法运算符在进行浮点数与整型数相例如加法运算符在进行浮点数与整型数相加时,首先进行类型强制转换,把整型数加时,首先进行类型强制转换,把整型数变为浮点数再相加的情况,就是强制多态变为浮点数再相加的情况,就是强制多态的实例。的实例。95.2 向上类型转换向上类型转换向上类型转换是指把一个派生类的对象向上类型转换是指把一个派生类的对象作为基类的对象来使用。作为基类的对象来使用。向上转型中有三点需要我们特别注意。向上转型中有三点需要我们特别注意。向上类型转换是安全的。向上类型转换是安全的。向上类型转换可以自动完成。向上类型转换可以自动完成。向上类型转换的过程中会丢失
5、子类型向上类型转换的过程中会丢失子类型信息。信息。105.2 向上类型转换向上类型转换【例例5-1】一个向上类型转换的例子。一个向上类型转换的例子。#include using namespace std;class B0 /基类基类B0声明声明public:void display()coutB0:display()endl;/公有成员函数公有成员函数class B1:public B0public:void display()coutB1:display()endl;class D1:public B1public:void display()coutD1:display()display
6、();/通过通过“对象指针对象指针-成员名成员名”的形式调用的形式调用display()成员函数成员函数int main()B0 b0;/声明声明B0类对象类对象B1 b1;/声明声明B1类对象类对象D1 d1;/声明声明D1类对象类对象B0*p;/声明声明B0类指针类指针pp=&b0;/B0类指针类指针p指向指向B0类对象类对象fun(p);p=&b1;/B0类指针类指针p指向指向B1类对象类对象fun(p);p=&d1;/B0类指针类指针p指向指向D1类对象类对象fun(p);return 0;115.3 功能早绑定和晚绑定功能早绑定和晚绑定v功能早绑定功能早绑定(编译时的多态性编译时的多
7、态性):):绑定是在程序绑定是在程序编译阶段完成。编译阶段完成。功能早绑定时,系统用实参与功能早绑定时,系统用实参与形参进行匹配,对于同名的重载函数便根据参形参进行匹配,对于同名的重载函数便根据参数上的差异进行区分,然后进行绑定,从而实数上的差异进行区分,然后进行绑定,从而实现了编译时的多态性。现了编译时的多态性。v功能晚绑定功能晚绑定(运行时的多态性运行时的多态性):):绑定是在程序绑定是在程序运行阶段完成的。即当程序调用到某一函数名运行阶段完成的。即当程序调用到某一函数名时,才去寻找和连接其程序代码,对面向对象时,才去寻找和连接其程序代码,对面向对象程序设计而言,就是当对象接收到某一消息时
8、,程序设计而言,就是当对象接收到某一消息时,才去寻找和连接相应的方法。才去寻找和连接相应的方法。125.4 实现功能晚绑定实现功能晚绑定虚函数虚函数v成员函数的定义语法是:成员函数的定义语法是:virtual virtual 函数类型函数类型 函数名函数名(形参表形参表)函数体函数体 135.2 向上类型转换向上类型转换【例例5-35-3】有一个交通工具类有一个交通工具类vehiclevehicle,将它作为基类派,将它作为基类派生出汽车类生出汽车类motor_ vehicle motor_ vehicle,再将汽车类,再将汽车类motor_ motor_ vehicle vehicle 作为
9、基类派生出小汽车类作为基类派生出小汽车类carcar和卡车类和卡车类trucktruck,声明这些类并定义一个虚函数用来显示各类信息。程序声明这些类并定义一个虚函数用来显示各类信息。程序如下:如下:#include#include using namespace std;using namespace std;class vehicleclass vehicle/基类基类vehiclevehicle声明声明public:public:virtual void message()/virtual void message()/虚成员函数虚成员函数 coutvehicle message endl
10、;coutvehicle message endl;private:private:int wheels;/int wheels;/车轮个数车轮个数float weight;/float weight;/车重车重;145.2 向上类型转换向上类型转换class motor_vehicle:public vehicle/vehicleclass motor_vehicle:public vehicle/vehicle派生类派生类motor_vehiclemotor_vehicle声明声明public:public:void message()cout motor_ vehicle message
11、 endl;void message()cout motor_ vehicle message endl;private:private:int passengers;/int passengers;/承载人数承载人数;class car:public motor_vehicle /motor_ vehicleclass car:public motor_vehicle /motor_ vehicle的派生类的派生类carcar声明声明public:public:void message()coutcar message endl;void message()coutcar message e
12、ndl;private:private:float engine;/float engine;/发动机的马力数发动机的马力数;class truck:public motor_vehicle/motor_vehicleclass truck:public motor_vehicle/motor_vehicle的派生类的派生类trucktruck声明声明 public:public:void message()cout truck message endl;void message()cout truck message message();/p-message();/调用基类成员函数调用基类成
13、员函数p=&m;p=&m;/vehicle /vehicle类指针类指针p p指向指向motor_ vehiclemotor_ vehicle类对象类对象p-message();/p-message();/调用调用motor_ vehiclemotor_ vehicle类成员函数类成员函数p=&c;p=&c;/vehicle /vehicle类指针类指针p p指向指向carcar类对象类对象p-message();/p-message();/调用调用carcar类成员函数类成员函数p=&t;p=&t;/vehicle /vehicle类指针类指针p p指向指向trucktruck类对象类对象p
14、-message();/p-message();/调用调用trucktruck类成员函数类成员函数 return 0;return 0;165.4 实现功能晚绑定实现功能晚绑定虚函数虚函数vC+C+规定,如果在派生类中,没有用规定,如果在派生类中,没有用virtualvirtual显式地给出虚函数声明,这时系显式地给出虚函数声明,这时系统就会遵循以下的规则来判断一个成员统就会遵循以下的规则来判断一个成员函数是不是虚函数:函数是不是虚函数:(1 1)该函数与基类的虚函数有相同的名称。)该函数与基类的虚函数有相同的名称。(2 2)该函数与基类的虚函数有相同的参数)该函数与基类的虚函数有相同的参数个
15、数及相同的对应参数类型。个数及相同的对应参数类型。(3 3)该函数与基类的虚函数有相同的返回)该函数与基类的虚函数有相同的返回类型或者满足赋值兼容规则的指针、引用型类型或者满足赋值兼容规则的指针、引用型的返回类型。的返回类型。175.4 实现功能晚绑定实现功能晚绑定虚函数虚函数说明:说明:v 通过定义虚函数来使用通过定义虚函数来使用C+C+提供的多态性机制时,派生类应该从它的基类提供的多态性机制时,派生类应该从它的基类公用派生。之所以有这个要求,是因为我们是在赋值兼容规则的基础上来公用派生。之所以有这个要求,是因为我们是在赋值兼容规则的基础上来使用虚函数的,而赋值兼容规则成立的前提条件是派生类
16、从其基类公用派使用虚函数的,而赋值兼容规则成立的前提条件是派生类从其基类公用派生。生。v 必须首先在基类中定义虚函数。由于必须首先在基类中定义虚函数。由于“基类基类”与与“派生类派生类”是相对的,因是相对的,因此,这项说明并不表明必须在类等级的最高层类中声明虚函数。在实际应此,这项说明并不表明必须在类等级的最高层类中声明虚函数。在实际应用中,应该在类等级内需要具有动态多态性的几个层次中的最高层类内首用中,应该在类等级内需要具有动态多态性的几个层次中的最高层类内首先声明虚函数。先声明虚函数。v 在派生类对基类中声明的虚函数进行重新定义时,关键字在派生类对基类中声明的虚函数进行重新定义时,关键字v
17、irtualvirtual可以写可以写也可以不写。但为了增强程序的可读性,最好在对派生类的虚函数进行重也可以不写。但为了增强程序的可读性,最好在对派生类的虚函数进行重新定义时也加上关键字新定义时也加上关键字virtualvirtual。v 如果在派生类中没有对基类的虚函数重新定义,则派生类简单地继承其直如果在派生类中没有对基类的虚函数重新定义,则派生类简单地继承其直接基类的虚函数。接基类的虚函数。v 虽然使用对象名和点运算符的方式也可以调用虚函数,例如语句:虽然使用对象名和点运算符的方式也可以调用虚函数,例如语句:c.message();c.message();可以调用虚函数可以调用虚函数ca
18、r:message()car:message()。但是这种调用在编译时进行的是功能。但是这种调用在编译时进行的是功能早绑定,它没有充分利用虚函数的特性。只有通过基类指针或引用访问虚早绑定,它没有充分利用虚函数的特性。只有通过基类指针或引用访问虚函数时才能获得运行时的多态性。函数时才能获得运行时的多态性。185.4 实现功能晚绑定实现功能晚绑定虚函数虚函数v 一个虚函数无论被公用继承多少次,它仍然保持其虚函数一个虚函数无论被公用继承多少次,它仍然保持其虚函数的特性。的特性。v 虚函数必须是其所在类的成员函数,而不能是友元函数,虚函数必须是其所在类的成员函数,而不能是友元函数,也不能是静态成员函数
展开阅读全文