C++面向对象程序设计 教学课件 ppt 作者 张德慧 周元哲 主编第8章 多态性 虚函数

上传人:w****i 文档编号:94381194 上传时间:2019-08-06 格式:PPT 页数:46 大小:248.50KB
返回 下载 相关 举报
C++面向对象程序设计 教学课件 ppt 作者 张德慧 周元哲 主编第8章  多态性  虚函数_第1页
第1页 / 共46页
C++面向对象程序设计 教学课件 ppt 作者 张德慧 周元哲 主编第8章  多态性  虚函数_第2页
第2页 / 共46页
C++面向对象程序设计 教学课件 ppt 作者 张德慧 周元哲 主编第8章  多态性  虚函数_第3页
第3页 / 共46页
C++面向对象程序设计 教学课件 ppt 作者 张德慧 周元哲 主编第8章  多态性  虚函数_第4页
第4页 / 共46页
C++面向对象程序设计 教学课件 ppt 作者 张德慧 周元哲 主编第8章  多态性  虚函数_第5页
第5页 / 共46页
点击查看更多>>
资源描述

《C++面向对象程序设计 教学课件 ppt 作者 张德慧 周元哲 主编第8章 多态性 虚函数》由会员分享,可在线阅读,更多相关《C++面向对象程序设计 教学课件 ppt 作者 张德慧 周元哲 主编第8章 多态性 虚函数(46页珍藏版)》请在金锄头文库上搜索。

1、C+面向对象程序设计教学内容,第1章 C+概述 第2章 类和对象 第3章 面向对象程序设计概述 第4章 进一步学习类和对象 第5章 堆与复制构造函数 第6章 继承性:派生类 第7章 运算符重载 第8章 虚函数和多态性 第9章 模板 第10章 类库和C+的标准模板库STL 第11章 输入输出流 第12章 异常处理,第8章 多态性与虚函数,8.1 多态性概述 8.2 静态联编和动态联编 8.3 虚函数 8.4 纯虚函数和抽象类 8.5 应用举例,面向对象程序设计的特征,抽象性(Abstraction) 封装性(Encapsulation) 继承性(Inheritance) 多态性(Polymorp

2、hism),8.1 多态性概述,polymorphism,“many forms”:即多种形态 在自然语言中,多态性即是“一词多义”; 更准确地说,多态性是指相同的动词作用到不同类型的对象上, 例如: 驾驶摩托车 驾驶汽车 驾驶飞机 驾驶轮船 驾驶宇宙飞船,什么是多态性?(OOP),当不同对象接受到相同的消息产生不同的动作,这种性质称为多态性。 通俗地说,多态性是指用一个名字定义不同的函数,这些函数执行不同但又类似的操作, 即用同样的接口访问功能不同的函数,从而实现“一个接口,多种方法”。,多态性的例子,在C语言中,由于不支持多态,求绝对值的动作要求三个不同的函数名字: abs(), labs

3、(),fabs() 分别用来求整数,长整数、浮点数的绝对值。 在C+语言中,由于支持多态,求绝对值的动作可以只用一个函数名: abs(),面向对象程序设计的精华,通过一个简单的接口对不同的实现进行概念上的简化。 class walkman virtual void on( )=0; virtual void off( )=0; virtual void play( )=0; virtual void record( )=0; virtual void stop( )=0; ; Cassette player, CD player, MD player, MP3 player;,提供给用户相同的

4、接口,应用多态性的好处,多态应用于OOP的目的是允许用一个名字来指定动作的一般类(即逻辑上相似的动作)。 从而带来以下的好处: 提高了处理问题的抽象级别; 降低了程序设计时的复杂性; (程序员只需记住一个接口,而不是好几个。),C+实现的多态性,编译时多态性: 函数重载 运算符重载 模板 运行时多态性: 借助虚函数来获得,在C+中,多态性的实现与联编(Binding)这一概念有关。,8.2 静态联编和动态联编,什么叫联编(Binding)? 一个源程序需要经过编译、连接,才能成为可执行代码。 上述过程中需要将一个函数调用链接上相应的函数代码,这一过程称为联编。 联编的目的是要建立函数调用与函数

5、体之间的联系, 即将一个函数调用连接到一函数的入口地址。,C+支持两种联编,静态联编:在程序被编译时进行联编;(早联编) 程序执行快,但灵活性较小。 动态联编:在程序运行时联编。(晚联编,滞后联编) 灵活性高,程序执行慢。 动态联编是C+实现运行时多态性的关键因素。,8.3 虚函数,virtual float area( ) return -1; virtual 关键字的作用:指示C+编译器对该函数的调用进行动态联编。,#include class shape public: float area( ) return -1; ; class circle:public shape float

6、radius; public: void circle(float r) radius = r; float area( ) return 3.14159*radius*radius; ;,为什么需要虚函数,void main() shape obj, *ptr; circle c(3.6); ptr= ,为什么需要虚函数,The pointer of base class “shape“.,求圆形的面积,输出的结果为: 1 1 为什么会是这样? 原因在于这里只是用了静态联编。 前后两次ptr-area( )调用都链接到下面的函数实现: float area( ) return -1;,输出的

7、结果分析,#include class shape public: virtual float area( ) return -1; ; class circle:public shape float radius; public: void circle(float r) radius = r; float area( ) return 3.14159*radius*radius; ;,虚函数,被关键字virtual说明的函数称为虚函数,void main() shape obj, *ptr; circle c(3.6); ptr= ,使用虚函数后的输出结果,The pointer of b

8、ase class “shape“.,C+的编译器对虚函数调用采取动态联编方式,输出结果: 1 40.715,虚函数的定义,冠以关键字virtual的成员函数称为虚拟函数,简称虚函数。 说明虚函数的方法如下: virtual ( ) 虚函数是成员函数,而且是非static的成员函数。 包含虚函数的类被称为多态类。,class shape public: virtual float area( ) ; ; class triangle:public shape float H,W; public: triangle(float h,float w)H=h;W=w; float area( ) r

9、eturn H*W*0.5; ;,在派生类中,虚函数被重新定义以实现不同的操作。 这种方式称为函数超越(overriding),又称为函数覆盖。,虚函数的使用分析,class rectangle:public shape float H,W; public: rectangle(float h,float w) H=h; W=w; float area( )return H*W; ;,void main( ) shape *s; triangle tri(3,4); rectangle rect(3,4); s= ,请注意:在这里以指针s所指的对象来确定执行虚函数area()的哪个版本。,“确

10、定”是在运行时执行的,这构成了运行时的多态性,虚函数是动态联编的基础,virtual 关键字的作用:指示C+编译器对该函数的调用进行动态联编。 尽管可以用对象名和点算符的方式调用虚函数,即向对象发送消息: tri.area( ) 或者 rect.area( ) 这时是静态联编方式。 只有当访问虚函数是通过基类指针s时才可获得运行时的多态性。,虚函数与重载函数的比较,1.从形式上说,重载函数要求函数有相同的函数名称,并有不同的参数序列; 2.重载函数可以是成员函数和非成员函数;,而虚函数要求这三项(函数名称、返回值和参数序列)完全相同,即具有完全相同的函数原型。 而虚函数只能是成员函数。,虚函数

11、与重载函数的比较(续),3.对重载函数的调用是以所传递参数序列的差别(参数个数或类型的不同)作为调用不同函数的依据;,虚拟函数是根据对象的不同去调用不同类的虚拟函数。,虚函数在运行时表现出多态功能,正是C+的精髓之一;而重载函数不具备这一功能。,虚函数小结,如果某类中的一个成员函数被说明为虚函数,这就意味着该成员函数在派生类中可能有不同的实现。 为了实现运行时的多态性,调用虚函数应该通过第一次定义该虚函数的基类对象指针 只有通过指针或引用标识对象来操作虚函数时,才对虚函数采取动态联编方式。 如果采用一般类型的标识对象来操作虚函数,则将采用静态联编方式调用虚函数。,虚函数小结(续),构造函数不能

12、是虚拟的,但析构函数可以是虚拟的。 设计C+程序时,一般在基类中定义处理某一问题的接口和数据元素,而在派生类中定义具体的处理方法。 通常都将基类中处理问题的接口设计成虚函数,然后利用基类对象指针调用虚函数,从而达到单一接口,多种功能的目的。,8.4 纯虚函数和抽象类,纯虚函数是指在基类中声明但是没有定义的虚函数,而且设置函数值等于零。 virtual type func_name(parameter list) =0; 通过将虚函数声明为纯虚函数可以强制在派生类中重新定义虚函数。 如果没有在派生类中重新定义,编译器将会报告错误。,class shape public: virtual floa

13、t area( )=0; /A PURE VIRTUAL FUNCTION ; class triangle:public shape float H,W; public: triangle(float h,float w)H=h;W=w; float area( )return H*W*0.5; ;,纯虚函数的例子,纯虚函数,抽象类,抽象类:包含有纯虚函数的类称为抽象类。 不能说明抽象类的对象,但能说明指向抽象类的指针,一个抽象类只能作为基类来派生其他的类。 抽象类的指针用于指向该抽象类的派生类的对象。,void main( ) shape *s; triangle tri(3,4); re

14、ctangle rect(3,4); s= ,抽象类的例子,Shape是抽象类,只能定义指向该类对象的指针,8.5 应用举例,人员管理系统: 有三类人员:经理、技术人员、推销人员,还有销售经理。 月薪:经理:8000元/月;技术人员:100元/小时;推销人员:4%提成;销售经理:5000元月+5%提成。,问题分析,在前面一章中,这个程序有两点不足: 基类的成员函数pay( )和displayStatus( )的函数体均为空,在实现部分仍要写出函数体,显得冗余。 在main()函数中,建立了四个不同类的对象,对它们进行了类似的操作,但是却重复写了四遍类似的语句,程序不够简洁。,class emp

15、loyee protected: char *name; /姓名 int individualEmpNo; /个人编号 int grade; /级别 float accumPay; /月薪总额 static int employeeNo; /本公司职员 编号目前最大值 public: employee(); /构造函数 employee(); /析构函数 virtual void pay( )0; /计算月薪函数 virtual void promote(int); /升级函数 virtual void displayStatus( )0; /显示人员信息 ;,class technician

16、 : public employee /技术人员类 private: float hourlyRate; /每小时酬金 int workHours; /当月工作时数 public: technician(); /构造函数 void promote(int); void pay(); /计算月薪函数 void displayStatus(); /显示人员信息 ;,class salesman:virtual public employee /兼职推销员类 protected: float CommRate; /按销售额提取酬金的百分比 float sales; /当月销售额 public: salesman(); /构造函数 void promote(int); void pay

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号