




已阅读5页,还剩24页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1,C+程序设计,多态性与虚函数,2,第5章 多态性与虚函数,什么是多态性 向上类型转换 功能早绑定和晚绑定 实现功能晚绑定虚函数 纯虚函数和抽象类 学生信息管理系统中的多态性,本章学习要点,3,第5章 多态性与虚函数,多态性是指用一个名字定义不同的函数,这些函数执行不同但又类似的操作,从而可以使用相同的调用方式来调用这些具有不同功能的同名函数。 实现“一个接口,多种方法”,4,5.1 什么是多态性,多态性可以分为4类: 参数多态 包含多态 重载多态 强制多态。,5,5.1 什么是多态性,参数多态如函数模板和类模板。 由函数模板实例化的各个函数都具有相同的操作,而这些函数的参数类型却各不相同。同样地,由类模板实例化的各个类都具有相同的操作,而操作对象的类型是各不相同的。,6,5.1 什么是多态性,包含多态是研究类族中定义于不同类中的同名成员函数的多态行为,主要是通过虚函数来实现的。,7,5.1 什么是多态性,重载多态如函数重载、运算符重载等。前面我们学习过的普通函数及类的成员函数的重载都属于重载多态。,8,5.1 什么是多态性,强制多态是指将一个变元的类型加以变化,以符合一个函数(或操作)的要求,例如加法运算符在进行浮点数与整型数相加时,首先进行类型强制转换,把整型数变为浮点数再相加的情况,就是强制多态的实例。,9,5.2 向上类型转换,向上类型转换是指把一个派生类的对象作为基类的对象来使用。 向上转型中有三点需要我们特别注意。 向上类型转换是安全的。 向上类型转换可以自动完成。 向上类型转换的过程中会丢失子类型信息。,10,5.2 向上类型转换,【例5-1】一个向上类型转换的例子。 #include using namespace std; class B0 /基类B0声明 public: void display()coutdisplay(); /通过“对象指针-成员名”的形式调用display()成员函数 int main() B0 b0; /声明B0类对象 B1 b1; /声明B1类对象 D1 d1; /声明D1类对象 B0 *p; /声明B0类指针p p=,11,5.3 功能早绑定和晚绑定,功能早绑定(编译时的多态性):绑定是在程序编译阶段完成。功能早绑定时,系统用实参与形参进行匹配,对于同名的重载函数便根据参数上的差异进行区分,然后进行绑定,从而实现了编译时的多态性。 功能晚绑定(运行时的多态性):绑定是在程序运行阶段完成的。即当程序调用到某一函数名时,才去寻找和连接其程序代码,对面向对象程序设计而言,就是当对象接收到某一消息时,才去寻找和连接相应的方法。,12,5.4 实现功能晚绑定虚函数,成员函数的定义语法是: virtual 函数类型 函数名(形参表) 函数体 ,13,5.2 向上类型转换,【例5-3】 有一个交通工具类vehicle,将它作为基类派生出汽车类motor_ vehicle ,再将汽车类motor_ vehicle 作为基类派生出小汽车类car和卡车类truck,声明这些类并定义一个虚函数用来显示各类信息。程序如下: #include using namespace std; class vehicle /基类vehicle声明 public: virtual void message() /虚成员函数 cout“vehicle message “endl; private: int wheels; /车轮个数 float weight; /车重 ;,14,5.2 向上类型转换,class motor_vehicle: public vehicle /vehicle派生类motor_vehicle声明 public: void message() cout“ motor_ vehicle message “endl; private: int passengers; /承载人数 ; class car: public motor_vehicle /motor_ vehicle的派生类car声明 public: void message() cout“car message “endl; private: float engine; /发动机的马力数 ; class truck: public motor_vehicle /motor_vehicle的派生类truck声明 public: void message() cout“ truck message “endl; private: int loadpay ; /载重量 ;,15,5.2 向上类型转换,int main() vehicle v,*p; /声明vehicle类对象和基类指针p motor_vehicle m; /声明motor_ vehicle类对象 car c; /声明car类对象 truck t; /声明truck类对象 p= ,16,5.4 实现功能晚绑定虚函数,C+规定,如果在派生类中,没有用virtual显式地给出虚函数声明,这时系统就会遵循以下的规则来判断一个成员函数是不是虚函数: (1)该函数与基类的虚函数有相同的名称。 (2)该函数与基类的虚函数有相同的参数个数及相同的对应参数类型。 (3)该函数与基类的虚函数有相同的返回类型或者满足赋值兼容规则的指针、引用型的返回类型。,17,5.4 实现功能晚绑定虚函数,说明: 通过定义虚函数来使用C+提供的多态性机制时,派生类应该从它的基类公用派生。之所以有这个要求,是因为我们是在赋值兼容规则的基础上来使用虚函数的,而赋值兼容规则成立的前提条件是派生类从其基类公用派生。 必须首先在基类中定义虚函数。由于“基类”与“派生类”是相对的,因此,这项说明并不表明必须在类等级的最高层类中声明虚函数。在实际应用中,应该在类等级内需要具有动态多态性的几个层次中的最高层类内首先声明虚函数。 在派生类对基类中声明的虚函数进行重新定义时,关键字virtual可以写也可以不写。但为了增强程序的可读性,最好在对派生类的虚函数进行重新定义时也加上关键字virtual。 如果在派生类中没有对基类的虚函数重新定义,则派生类简单地继承其直接基类的虚函数。 虽然使用对象名和点运算符的方式也可以调用虚函数,例如语句:c.message (); 可以调用虚函数car: message () 。但是这种调用在编译时进行的是功能早绑定,它没有充分利用虚函数的特性。只有通过基类指针或引用访问虚函数时才能获得运行时的多态性。,18,5.4 实现功能晚绑定虚函数,一个虚函数无论被公用继承多少次,它仍然保持其虚函数的特性。 虚函数必须是其所在类的成员函数,而不能是友元函数,也不能是静态成员函数,因为虚函数调用要靠特定的对象来决定该激活哪个函数。但是虚函数可以在另一个类中被声明为友元函数。 内联函数不能是虚函数,因为内联函数是不能在运行中动态确定其位置的。即使虚函数在类的内部定义,编译时仍将其看作是非内联的。 构造函数不能是虚函数。因为虚函数作为运行过程中多态的基础,主要是针对对象的,而构造函数是在对象产生之前运行的,因此虚构造函数是没有意义的。 析构函数可以是虚函数,而且通常说明为虚函数。,19,5.4 实现功能晚绑定虚函数,在析构函数前面加上关键字virtual进行说明,则称该析构函数为虚析构函数。虚析构函数的声明语法为: virtual 类名();,20,5.2 向上类型转换,【例5-4】 在交通工具类vehicle中使用虚析构函数。 #include using namespace std; class vehicle /基类vehicle声明 public: vehicle () /构造函数 virtual vehicle () /虚析构函数 cout“vehicle : vehicle() “endl; private: int wheels; float weight; class motor_vehicle:public vehicle /声明vehicle的公用派生类motor_ vehicle public: motor_vehicle () /派生类构造函数 motor_vehicle () /派生类析构函数 cout“motor_ vehicle : motor_ vehicle() “endl; private: int passengers; int main() vehicle *p; /声明vehicle类指针p p=new motor_vehicle; delete p; return 0; ,21,5.4 实现功能晚绑定虚函数,在一个派生类中重新定义基类的虚函数不同于一般的函数重载: 函数重载处理的是同一层次上的同名函数问题,而虚函数处理的是同一类族中不同派生层次上的同名函数问题,前者是横向重载,后者可以理解为纵向重载。但与重载不同的是: 同一类族的虚函数的首部是相同的,而函数重载时函数的首部是不同的(参数个数或类型不同)。 重载函数可以是成员函数或普通函数,而虚函数只能是成员函数; 重载函数的调用是以所传递参数序列的差别作为调用不同函数的依据;虚函数是根据对象的不同去调用不同类的虚函数; 虚函数在运行时表现出多态功能,这是C+的精髓;而重载函数则在编译时表现出多态性。,22,5.5 纯虚函数和抽象类,纯虚函数是一个在基类中说明的虚函数,它在该基类中没有定义,但要求在它的派生类中必须定义自己的版本,或重新说明为纯虚函数。 纯虚函数的定义形式如下: class 类名 virtual 函数类型 函数名(参数表)=0; ;,23,5.2 向上类型转换,【例5-5】定义一个公共基类Shape,它表示一个封闭平面几何图形。然后,从Shape类派生出三角形类Trianglet、矩形类Rectangle和圆类Circle,在基类中定义纯虚函数show()和area(),分别用于显示图形信息和求相应图形的面积,并在派生类中根据不同的图形实现相应的函数。要求实现运行时的多态性。 #include #include using namespace std; const double PI=3.1415926535; class Shape/形状类 public: virtual void show()=0; virtual double area()=0; ;,24,5.2 向上类型转换,class Rectangle:public Shape/矩形类 public: Rectangle()length=0; width=0; Rectangle(double len, double wid) length= len;width = wid; double area()return length*width; /求面积 void show() cout“length=“lengtht“width=“widthendl; private: double length, width; ; /长宽 class Circle :public Shape/圆类 public: Circle()radius = 0; Circle(double r)radius = r; double area()return PI*radius*radius; /求面积 void show()cout“radius=“radiusendl; private: double radius;,25,5.2 向上类型转换,class Triangle:public Shape/三角形类 public: Triangle()a=0;b=0;c=0; Triangle(double x,double y,double z)a = x;b = y;c = z; double area()/求面积 double s=(a+b+c)/2.0; return sqrt(s*(s-a)*(s-b)*(s-c); void show() cout“a=“at“b=“bt“c=“cendl; private: double a, b,c; /三角形三边长 ;,26,5.2 向上类型转换,int main() Shape *s; Circle c(10); Rectangle r(6,8); Triangle t(3,4,5); c.show();/静态多态 coutshow(); coutarea()show(); coutarea()endl; return 0; ,27,5.5 纯虚函数和抽象类,如果一个类至少有一个纯虚函数,那么就称该类为抽象类。 对于抽象类的使用有以下几点规定: (1)由于抽象类中至少包含一个没有定义功能的纯虚函数。因此,抽象类只能作为其他类的基类来使用,不能建立抽象类对象,这只能用来为派生类提供一个接口规范,其纯虚函数的实现由派生类给出。 (2)不允许从具体类派生出抽象类,。所谓具体类,就是不包含纯虚函数的普通类。 (3)抽象类不能用作参数类型、函数返回类型或显式转换的类型。 (
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2023年元旦小孩的主持词(8篇)
- 2022年自助餐厅圣诞节方案范文
- 环境友好型厂房建设方案
- 供水管网老旧设施更换工程规划设计方案(范文)
- 书籍封面的制作与设计
- 汛期安全教育知识培训
- 山西晋中理工学院《资源环境审计学》2023-2024学年第二学期期末试卷
- 广州番禺职业技术学院《政府与非盈利组织会计》2023-2024学年第二学期期末试卷
- 江苏卫生健康职业学院《电视新闻节目制作》2023-2024学年第二学期期末试卷
- 南京铁道职业技术学院《大数据分析工具与技术》2023-2024学年第二学期期末试卷
- 销售基础编码规则模板
- 水电安装施工组织设计施工组织设计
- 2023年陕西普通高中学业水平考试通用技术试题
- 快递员(初级)理论培训考试题库600题(含答案)
- 中西医执业医师《第二单元》模拟试题卷一(精选)
- 二年级看图写话讲评
- 审计业务约定书
- 酒店OTA宾客服务操作流程
- 人教版高中化学选修二测试题及答案解析
- LY/T 2692-2016榉树育苗技术规程
- GB/T 5357-1998内六角花形扳手
评论
0/150
提交评论