团队学生技术交流讲座

上传人:F****n 文档编号:95491821 上传时间:2019-08-19 格式:PPT 页数:45 大小:2.16MB
返回 下载 相关 举报
团队学生技术交流讲座_第1页
第1页 / 共45页
团队学生技术交流讲座_第2页
第2页 / 共45页
团队学生技术交流讲座_第3页
第3页 / 共45页
团队学生技术交流讲座_第4页
第4页 / 共45页
团队学生技术交流讲座_第5页
第5页 / 共45页
点击查看更多>>
资源描述

《团队学生技术交流讲座》由会员分享,可在线阅读,更多相关《团队学生技术交流讲座(45页珍藏版)》请在金锄头文库上搜索。

1、理解C+虚拟与多态机制,机器视觉团队技术交流讲座 第02讲,主讲教师 杨 程,目 录,多态性 虚函数与动态绑定 纯虚函数与抽象类 实例讲解 习题和课后阅读资料,多态性,多态性的定义,何谓多态性? 多态性是指给同样的接口发送同样的消息会导致不同的行为。 多态意味着一个对象有着多重特征,可以在特定的情况下,表现不同的状态,从而对应着不同的属性和方法。 多态性是面向对象程序设计的重要特征之一。 若程序设计语言不支持多态性,不能称为面向对象的语言。,C+多态性,C+有哪些多态性机制? 函数重载 运算符重载 虚函数 函数重载和运算符重载是编译时体现出来的多态性,虚函数则体现了运行时的多态性。,虚函数与动

2、态绑定,示例:乐器类继承体系,类定义 Instrument 乐器 Wind 管乐器 Woodwind 木管乐器 Brass 铜管乐器 Percussion 打击乐器 Stringed 弦乐器,接口说明 play 演奏 adjust 调整乐器 what 显示乐器信息,类型的向上转换(Upcasting),将派生类地址(指针或引用)沿着继承树向上的方向赋给基类指针(赋值兼容原则) Upcasting将对象按传址(by address)而非传值(by value)方式进行操作,而多态性需通过Upcasting来体现。,我们想做什么?,提供给用户一个通用的不变的系统使用接口函数tune(),无论类进行

3、了怎样的变动,这个接口都能正常可靠地工作(总能按照我们的期望选出正确的乐器演奏),我们想做什么?,我们的要求是合理的,这种要求系统具备动态识别能力的需求,在实际运行的很多软件系统当中都是一项基本要求,这正是要求系统具备多态性。 void tune(Instrument / Upcasting ,先看一个例子,#include using namespace std; enum note middleC, Csharp, Eflat ;. class Instrument public: void play(note) const cout “Instrument:play“ endl; ; /

4、 Wind objects are Instruments / because they have the same interface: class Wind : public Instrument public: / Redefine interface function: void play(note) const cout “Wind:play“ endl; ;,void tune(Instrument 我们定义了Wind对象flute,通过接口tune操作play函数,显然我们希望flute对象能正确地调用Wind类的play函数,运行的结果,#include using names

5、pace std; enum note middleC, Csharp, Eflat ;. class Instrument public: void play(note) const cout “Instrument:play“ endl; ; / Wind objects are Instruments / because they have the same interface: class Wind : public Instrument public: / Redefine interface function: void play(note) const cout “Wind:pl

6、ay“ endl; ;,void tune(Instrument 程序却调用了基类Instrument的play函数,显然这不是我们希望的结果! 问题出在哪儿了呢?,改动一下例子,#include using namespace std; enum note middleC, Csharp, Eflat ;. class Instrument public: virtual void play(note) const cout “Instrument:play“ endl; ; / Wind objects are Instruments / because they have the sam

7、e interface: class Wind : public Instrument public: / Redefine interface function: void play(note) const cout “Wind:play“ endl; ;,void tune(Instrument 将基类函数play函数定义成为虚函数(virtual function),初见虚函数,虚函数(virtual function)的定义 virtual 返回类型 函数名(参数表); class Shape private: public: virtual void Draw() cout “Dra

8、w a shape”endl; ;,派生类中的虚函数,虚函数是类成员函数(class member function); 在派生类(derived class)中对虚函数的实现重新定义称之为覆盖(override) 虚函数的“身份”在继承之间能被持续传递下去,再次运行,结果,#include using namespace std; enum note middleC, Csharp, Eflat ;. class Instrument public: virtual void play(note) const cout “Instrument:play“ endl; ; / Wind obj

9、ects are Instruments / because they have the same interface: class Wind : public Instrument public: / Redefine interface function: void play(note) const cout “Wind:play“ endl; ;,void tune(Instrument 这次结果是我们希望的结果! 我们引入了虚函数机制,导致了这样的结果。,“神奇的” 执行方式 ?,以基类指针运行虚函数,程序就能执行我们所期望的正确的派生类的函数体,虚函数为什么会有这样“神奇的”运行机制

10、呢? 通过继承而相关的不同类,他们的对象能够对同一个函数作出不同的响应.这样“神奇的” 多态性是怎样实现的呢?,静态绑定与动态绑定,绑定(binding) 程序自身彼此关联的过程,确定程序中的操作调用与执行该操作的代码间的关系。 静态绑定(early binding) 绑定过程出现在编译阶段,用对象名或者类名来限定要调用的函数。 动态绑定(dynamic/later binding) 绑定过程工作在程序运行时执行,在程序运行时才确定将要调用的函数。,“神奇的” 执行方式 动态绑定,C+的虚函数在运行时正是通过动态绑定实现多态机制的。 动态绑定是如何实现的呢? 动态绑定是通过编译器运用虚函数表V

11、TBL和虚表指针VPTR而实现,在运行时通过动态查询实现对正确函数体的绑定。,VTBL,编译器会为声明了虚函数的类建立一个虚函数表。 VTBL实际上是一个函数指针数组,每个虚函数占用这个数组的一个入口(slot)。 一个类只有一个VTBL,不管它有多少个实例。 派生类有自己的VTBL,但是派生类的VTBL与基类的VTBL有相同的函数排列顺序,同名的虚函数被放在两个数组的相同位置上。,VPTR,在创建类实例的时候,编译器还会在每个实例的内存布局中增加一个VPTR指针,该指针指向本类的VTBL。,最后,是动态联编,在调用此类的构造函数时,在类的构造函数中,编译器会隐含执行VPTR与VTBL的关联代

12、码,将VPTR指向对应的VTBL。这就将类与此类的VTBL联系了起来。 在调用类的构造函数时,指向基类的指针此时已经变成指向具体的类的this指针,依靠此this指针,进一步得到正确的VPTR,即可得到正确的VTBL,从而实现了多态性。在此时才能真正与函数体进行连接,这就是动态联编。,一个更大的例子,#include using namespace std; enum note middleC, Csharp, Cflat ; / Etc. class Instrument public: virtual void play(note) const cout “Instrument:play“

13、 endl; virtual char* what() const return “Instrument“; virtual void adjust(int) ; class Wind : public Instrument public: void play(note) const cout “Wind:play“ endl; char* what() const return “Wind“; void adjust(int) ;,class Percussion : public Instrument public: void play(note) const cout “Percussi

14、on:play“ endl; char* what() const return “Percussion“; void adjust(int) ; class Stringed : public Instrument public: void play(note) const cout “Stringed:play“ endl; char* what() const return “Stringed“; void adjust(int) ;,一个更大的例子,class Brass : public Wind public: void play(note) const cout “Brass:p

15、lay“ endl; char* what() const return “Brass“; ; class Woodwind : public Wind public: void play(note) const cout “Woodwind:play“ endl; char* what() const return “Woodwind“; ;,void tune(Instrument,一个更大的例子,int main() Wind flute; Percussion drum; Stringed violin; Brass flugelhorn; Woodwind recorder; tune(flute); tune(drum); tune(violin); tune(flugelhorn); tune(recorder); f(flugelhorn); /:,f(flugelhorn)函数调用的是哪个版本的adjust()函数呢?,虚函数的特点, 实现动态多态性时,必须使用基类类型的指针(pointer)或引用(reference)型变量,通过该变量引用虚函数,才能实现动态的多态性。 只有类的成员函数才能说明为虚

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

最新文档


当前位置:首页 > 办公文档 > PPT模板库 > PPT素材/模板

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