多态与动态联编.ppt
《多态与动态联编.ppt》由会员分享,可在线阅读,更多相关《多态与动态联编.ppt(24页珍藏版)》请在三一办公上搜索。
1、第11章 多态与动态联编,本章教学目标:理解虚拟函数、动态多态性和动态联编地概念。了解虚拟函数和动态联编对实现动态多态地作用。理解虚拟函数地声明、定义方法和访问属性。理解纯虚拟函数和抽象类地概念,掌握纯虚拟函数和抽象类的定义方法。了解抽象类和具体类的区别。了解虚拟析构函数的概念和作用,掌握其声明和使用方法。理解动态联编的实现机理,学会使用动态多态特性。,第11章 多态与动态联编,11.1虚拟函数、动态多态性与动态联编 11.2虚拟函数的访问属性 11.3纯虚拟函数与抽象类 11.4虚拟函数应用举例 11.5虚拟析构函数 11.6动态联编的实现机理,11.1 虚拟函数、动态多态性与动态联编,虚拟
2、函数(virtual function)是 C+进行 OOP 最富魅力的特征,灵活运用虚拟函数可以构造高度抽象和重用性好的程序。/例11.1 虚拟函数的定义和使用。#includeclass Base public:virtual void vfun(void)/用关键字virtual定义虚拟函数vfun()coutBase vfunn;class Drv1:public Base public:void vfun(void)coutDrv1 vfunn;,class Drv2:public Base;class Drv3:public Base public:void vfun(void)c
3、outDrv3 vfunn;class DDrv:public Drv1 public:void vfun(void)coutDDrv vfunn;void main()Base*vp;/同一接口,多种方法:,vp=new Base;vp-vfun();vp=new Drv1;vp-vfun();vp=new Drv2;vp-vfun();vp=new Drv3;vp-vfun();vp=new DDrv;vp-vfun();/*程序的执行结果如下:Base vfunDrv1 vfunBase vfunDrv3 vfunDDrv vfun*/,此例中,用关键字virtual在基类Base中定义
4、了一个虚拟函数vfun(),同时在派生类Drv1和Drv3以及Drv1的派生类DDrv中分别定义了一个接口完全相同的函数(可省略关键字 virtual,系统自动地将其定义为virtual,但从可读性方面考虑建议不要省略virtual),但在派生类 Drv2中没有定义 vfun(),这样做是为了对比地说明虚拟函数的用法。为了使用虚拟函数必须使用指向基类的指针,本例中,在主函数中定义了一个指向基类Base的指针vp,在C+中一个指向基类的指针可以用来指向其派生类的对象。访问非虚拟函数是编译时决定的,称为“静态联接”(或“静态约束”、“静态装订”:static binding,或“早期约束”:ear
5、ly binding);访问虚拟函数是在程序运行时动态决定的,称为“动态联接”(或“动态约束”、“动态装订”:dynamic binding,或“晚期约束”:lately binding)。,虚拟函数:基类中被关键字 virtual说明并在一个或多个派生类中被重新定义的函数原型完全一致的成员函数。关于虚拟函数应注意以下几点:除虚拟析构函数外,虚拟函数要求函数原型必须完全相同(函数体可不同),否则视为重载函数;虚拟函数必须是类的成员函数(静态成员函数和构造函数除外),一般说来,外部函数不能声明为虚拟函数;友元不能声明为虚拟函数,但虚拟函数可以是另一个类的友元;析构函数可以是虚拟函数,但构造函数不
6、能为虚拟函数。当基类中的析构函数定义为虚拟函数以后,派生类中的析构函数都自动定义为虚拟函数,很显然,派生类的析构函数与基类的析构函数是不同名的。如果想使用虚拟函数进行动态约束,则必须用指向基类的指针或引用来访问它,否则将为静态联编,使用虚拟函数的最大优点是:通过动态装订构造了一个抽象接口,提高了模块的独立性和易维护性。在C+中,利用虚拟函数和多态性,使得基类和派生类之间形成一种从抽象到具体、从一般到特殊的层次关系。在基类中我们可以声明本类和派生类都共有的函数(即一般化、抽象化、通用化、泛化),同时允许在派生类中对其中的某些或全部函数进行特殊定义(具体化、特殊化、特化、)。这种方法更接近于人类的
7、思维方法,这也是虚拟函数和多态的重要性所在。,11.2 虚拟函数的访问属性,虚拟函数的访问属性不决定于动态联编函数的访问属性,而决定于访问语句中虚拟函数的静态访问属性,即决定于访问语句:指针变量-虚拟函数或者:引用变量虚拟函数中指针变量或引用变量所属类中的虚拟函数的访问属性。/例11.2 虚拟函数的访问属性。#includeclass A public:/virtual void vfun(void)/公有的虚拟函数 coutA vfunn;,class B:public A private:/void vfun(void)coutvfun();/通过指针pA调用虚拟函数vfun(),B b;
8、/定义B类的对象bA/*程序的执行结果如下:B vfunB vfunC vfun*/,在上面的程序中,定义了三个类:A派生出B,B派生出C。在A、B、C中都定义了虚拟函数vfun(),但它们的访问属性不同。在A中,vfun()定义在public段内,是公有虚拟函数,在B和C中,vfun()都定义在private段内,都是私有虚拟函数,在main()函数中第句以及运行结果的第一行表明,虽然B类的vfun()是私有函数,但是仍然能够通过指针pA访问它,这是因为pA是指向A类的指针,而在A类中vfun()是公有函数,即虚拟函数的访问属性是由访问形式:pA-vfun();的属性决定的,而不是由它实际访
9、问的虚拟函数的属性决定的,也就是说,虚拟函数的访问属性是静态决定的,而不是动态决定的。main()函数中第和句也是基于同样理由。其中第句是通过引用来访问虚拟函数,第句还说明指向基类的指针可以访问其下两级甚至更多级派生类中的虚拟函数。main()函数中第句以注释的形式出现是因为它们无法通过编译,其原因是访问形式:pB-vfun();是私有的,因此编译时会产生“B:vfun()is not accessible”(“B:vfun()是不可访问”)的错误信息。,11.3 纯虚拟函数与抽象类,与普通函数一样,基类中的虚拟函数一般必须用一个函数体来定义其操作(可为空)。如果不作定义,可以把它声明为纯虚拟
10、函数(pure virtual function)。纯虚拟函数的定义格式如下:virtual 返回值类型 函数名(参数表)0;例如:class human.virtual int general()=0;/纯虚拟函数.;带有一个或多个纯虚拟函数的类叫做抽象类(abstract class)。抽象类只能作为其他类的基类,因此通常把抽象类称为抽象基类。,C+规定,不能建立抽象类的对象,也不能把抽象类作为函数的参数类型或返回值类型,但可以定义指向抽象类的指针和不需初始化的抽象类引用。任何由抽象类派生出来的派生类都必须重新声明它所继承的全部纯虚拟函数,不管这些纯虚拟函数在该派生类中作为普通的虚拟函数还
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 动态
链接地址:https://www.31ppt.com/p-6266151.html