书签 分享 收藏 举报 版权申诉 / 29
上传文档赚钱

类型《C++程序设计》课件第5章.ppt

  • 上传人(卖家):momomo
  • 文档编号:5787110
  • 上传时间:2023-05-09
  • 格式:PPT
  • 页数:29
  • 大小:913KB
  • 【下载声明】
    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 虚函数必须是其所在类的成员函数,而不能是友元函数,虚函数必须是其所在类的成员函数,而不能是友元函数,也不能是静态成员函数

    19、,因为虚函数调用要靠特定的对象也不能是静态成员函数,因为虚函数调用要靠特定的对象来决定该激活哪个函数。但是虚函数可以在另一个类中被来决定该激活哪个函数。但是虚函数可以在另一个类中被声明为友元函数。声明为友元函数。v 内联函数不能是虚函数,因为内联函数是不能在运行中动内联函数不能是虚函数,因为内联函数是不能在运行中动态确定其位置的。即使虚函数在类的内部定义,编译时仍态确定其位置的。即使虚函数在类的内部定义,编译时仍将其看作是非内联的。将其看作是非内联的。v 构造函数不能是虚函数。因为虚函数作为运行过程中多态构造函数不能是虚函数。因为虚函数作为运行过程中多态的基础,主要是针对对象的,而构造函数是在

    20、对象产生之的基础,主要是针对对象的,而构造函数是在对象产生之前运行的,因此虚构造函数是没有意义的。前运行的,因此虚构造函数是没有意义的。v 析构函数可以是虚函数,而且通常说明为虚函数。析构函数可以是虚函数,而且通常说明为虚函数。195.4 实现功能晚绑定实现功能晚绑定虚函数虚函数v在析构函数前面加上关键字在析构函数前面加上关键字virtualvirtual进进行说明,则称该析构函数为虚析构函行说明,则称该析构函数为虚析构函数。虚析构函数的声明语法为:数。虚析构函数的声明语法为:virtual virtual 类名类名();();205.2 向上类型转换向上类型转换【例例5-45-4】在交通工具

    21、类在交通工具类vehiclevehicle中使用虚析构函数。中使用虚析构函数。#include#include using namespace std;using namespace std;class vehicleclass vehicle /基类基类vehiclevehicle声明声明public:public:vehicle()vehicle()/构造函数构造函数virtual virtual vehicle()/vehicle()/虚析构函数虚析构函数coutvehicle:coutvehicle:vehicle()endl;vehicle()endl;private:private

    22、:int wheels;int wheels;float weight;float weight;class motor_vehicle:public vehicle /class motor_vehicle:public vehicle /声明声明vehiclevehicle的公用派生类的公用派生类motor_ vehiclemotor_ vehiclepublic:public:motor_vehicle()/motor_vehicle()/派生类构造函数派生类构造函数 motor_vehicle()/motor_vehicle()/派生类析构函数派生类析构函数coutmotor_ veh

    23、icle:coutmotor_ vehicle:motor_ vehicle()endl;motor_ vehicle()endl;private:private:int passengers;int passengers;int main()int main()vehicle vehicle*p;p;/声明声明vehiclevehicle类指针类指针p pp=new motor_vehicle;p=new motor_vehicle;delete p;delete p;215.4 实现功能晚绑定实现功能晚绑定虚函数虚函数在一个派生类中重新定义基类的虚函数不同于一般的函数重载:在一个派生类中重

    24、新定义基类的虚函数不同于一般的函数重载:v 函数重载处理的是同一层次上的同名函数问题,而虚函数处理函数重载处理的是同一层次上的同名函数问题,而虚函数处理的是同一类族中不同派生层次上的同名函数问题,前者是横向的是同一类族中不同派生层次上的同名函数问题,前者是横向重载,后者可以理解为纵向重载。但与重载不同的是重载,后者可以理解为纵向重载。但与重载不同的是:同一类同一类族的虚函数的首部是相同的,而函数重载时函数的首部是不同族的虚函数的首部是相同的,而函数重载时函数的首部是不同的的(参数个数或类型不同参数个数或类型不同)。v 重载函数可以是成员函数或普通函数,而虚函数只能是成员函重载函数可以是成员函数

    25、或普通函数,而虚函数只能是成员函数;数;v 重载函数的调用是以所传递参数序列的差别作为调用不同函数重载函数的调用是以所传递参数序列的差别作为调用不同函数的依据;虚函数是根据对象的不同去调用不同类的虚函数;的依据;虚函数是根据对象的不同去调用不同类的虚函数;v 虚函数在运行时表现出多态功能,这是虚函数在运行时表现出多态功能,这是C+C+的精髓;而重载函的精髓;而重载函数则在编译时表现出多态性。数则在编译时表现出多态性。225.5 纯虚函数和抽象类纯虚函数和抽象类v纯虚函数是一个在基类中说明的虚函数,纯虚函数是一个在基类中说明的虚函数,它在该基类中没有定义,但要求在它的派它在该基类中没有定义,但要

    26、求在它的派生类中必须定义自己的版本,或重新说明生类中必须定义自己的版本,或重新说明为纯虚函数。为纯虚函数。v纯虚函数的定义形式如下:纯虚函数的定义形式如下:class class 类名类名 virtual virtual 函数类型函数类型 函数名函数名(参数表参数表)=0;)=0;235.2 向上类型转换向上类型转换【例例5-55-5】定义一个公共基类定义一个公共基类ShapeShape,它表示一个封闭平面,它表示一个封闭平面几何图形。然后,从几何图形。然后,从ShapeShape类派生出三角形类类派生出三角形类TriangletTrianglet、矩形类矩形类RectangleRectang

    27、le和圆类和圆类CircleCircle,在基类中定义纯虚函,在基类中定义纯虚函数数show()show()和和area()area(),分别用于显示图形信息和求相应图,分别用于显示图形信息和求相应图形的面积,并在派生类中根据不同的图形实现相应的函形的面积,并在派生类中根据不同的图形实现相应的函数。要求实现运行时的多态性。数。要求实现运行时的多态性。#include#include#include#includeusing namespace std;using namespace std;const double PI=3.1415926535;const double PI=3.14159

    28、26535;class Shape/class Shape/形状类形状类 public:public:virtual void show()=0;virtual void show()=0;virtual double area()=0;virtual double area()=0;245.2 向上类型转换向上类型转换class Rectangle:public Shape/class Rectangle:public Shape/矩形类矩形类public:public:Rectangle()length=0;width=0;Rectangle()length=0;width=0;Recta

    29、ngle(double len,double wid)length=len;width=Rectangle(double len,double wid)length=len;width=wid;wid;double area()return lengthdouble area()return length*width;/width;/求面积求面积void show()void show()coutlength=lengthtwidth=widthendl;coutlength=lengthtwidth=widthendl;private:private:double length,width;

    30、/double length,width;/长宽长宽class Circle:public Shape/class Circle:public Shape/圆类圆类public:public:Circle()radius=0;Circle()radius=0;Circle(double r)radius=r;Circle(double r)radius=r;double area()return PIdouble area()return PI*radiusradius*radius;/radius;/求面积求面积void show()coutradius=radiusendl;void sh

    31、ow()coutradius=radiusendl;private:private:double radius;double radius;255.2 向上类型转换向上类型转换class Triangle:public Shape/class Triangle:public Shape/三角形类三角形类public:public:Triangle()a=0;b=0;c=0;Triangle()a=0;b=0;c=0;Triangle(double x,double y,double z)a=x;b=Triangle(double x,double y,double z)a=x;b=y;c=z;

    32、y;c=z;double area()/double area()/求面积求面积 double s=(a+b+c)/2.0;double s=(a+b+c)/2.0;return sqrt(s return sqrt(s*(s-a)(s-a)*(s-b)(s-b)*(s-c);(s-c);void show()void show()couta=atb=btc=cendcouta=atb=btc=cendl;l;private:private:double a,b,c;/double a,b,c;/三角形三边长三角形三边长;265.2 向上类型转换向上类型转换int main()int main

    33、()Shape Shape*s;s;Circle c(10);Circle c(10);Rectangle r(6,8);Rectangle r(6,8);Triangle t(3,4,5);Triangle t(3,4,5);c.show();/c.show();/静态多态静态多态 coutcout圆面积:圆面积:c.area()endl;c.area()show();s-show();cout cout矩形面积:矩形面积:area()endl;area()show();s-show();cout cout三角形面积:三角形面积:area()endl;area()endl;return 0;

    34、return 0;275.5 纯虚函数和抽象类纯虚函数和抽象类v 如果一个类至少有一个纯虚函数,那么就称该类为抽象类。如果一个类至少有一个纯虚函数,那么就称该类为抽象类。v 对于抽象类的使用有以下几点规定:对于抽象类的使用有以下几点规定:(1 1)由于抽象类中至少包含一个没有定义功能的纯虚函数。因此,抽)由于抽象类中至少包含一个没有定义功能的纯虚函数。因此,抽象类只能作为其他类的基类来使用,不能建立抽象类对象,这只能用来象类只能作为其他类的基类来使用,不能建立抽象类对象,这只能用来为派生类提供一个接口规范,其纯虚函数的实现由派生类给出。为派生类提供一个接口规范,其纯虚函数的实现由派生类给出。(

    35、2 2)不允许从具体类派生出抽象类,。所谓具体类,就是不包含纯虚)不允许从具体类派生出抽象类,。所谓具体类,就是不包含纯虚函数的普通类。函数的普通类。(3 3)抽象类不能用作参数类型、函数返回类型或显式转换的类型。)抽象类不能用作参数类型、函数返回类型或显式转换的类型。(4 4)可以声明指向抽象类的指针或引用,此指针可以指向它的派生类,)可以声明指向抽象类的指针或引用,此指针可以指向它的派生类,进而实现动态多态性。进而实现动态多态性。(5 5)如果派生类中没有重新定义纯虚函数,则派生类只是简单继承基)如果派生类中没有重新定义纯虚函数,则派生类只是简单继承基类的纯虚函数,则这个派生类仍然是一个抽

    36、象类。如果派生类中给出了类的纯虚函数,则这个派生类仍然是一个抽象类。如果派生类中给出了基类所有纯虚函数的实现,则该派生类就不再是抽象类了,它是一个可基类所有纯虚函数的实现,则该派生类就不再是抽象类了,它是一个可以创建对象的具体类。以创建对象的具体类。(6 6)在抽象类中也可以定义普通成员函数或虚函数,虽然不能为抽象)在抽象类中也可以定义普通成员函数或虚函数,虽然不能为抽象类声明对象,但仍然可以通过派生类对象来调用这些不是纯虚函数的函类声明对象,但仍然可以通过派生类对象来调用这些不是纯虚函数的函数。数。28小结与复习建议小结与复习建议v主要内容主要内容 多态性的概念、虚函数、纯虚函数、多态性的概念、虚函数、纯虚函数、抽象类抽象类v达到的目标达到的目标 理解多态的概念,学会运用多态机制。理解多态的概念,学会运用多态机制。29

    展开阅读全文
    提示  163文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:《C++程序设计》课件第5章.ppt
    链接地址:https://www.163wenku.com/p-5787110.html

    Copyright@ 2017-2037 Www.163WenKu.Com  网站版权所有  |  资源地图   
    IPC备案号:蜀ICP备2021032737号  | 川公网安备 51099002000191号


    侵权投诉QQ:3464097650  资料上传QQ:3464097650
       


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

    163文库