欢迎来到天天文库
浏览记录
ID:53561698
大小:1.45 MB
页数:50页
时间:2020-04-19
《虚基类与虚函数.ppt》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、5.2.2虚基类1.虚基类的概念在C++语言中,一个类不能被多次说明为一个派生类的直接基类,但可以不止一次地成为间接基类。这就导致了一些问题。为了方便说明,先介绍多继承的“类格”表示法。派生类及其基类可用一有向无环图(DAG)表示,其中的箭头表示“由派生而来”。类的DAG常称为一个“类格”。复杂类格画出来通常更容易理解。例如:2021-9-191LLL对象数据成员例5-19A对象数据成员classLABL对象数据成员{public:B对象数据成员intnext;…};classA:publicLC类自己数据成员
2、C{};C的对象classB:publicL{};classC:publicA,publicB{public:这时,next有两个赋值语voidf(){next=0;}};句next=0;具有二义性,它是将A::next置为零,还是将B::next置为零,或者将两者都置为0,需要在函数f()中被显式的说明.如果希望间接基类L与其派生类的关系是如下图LABCC++语言提供了这种描述手段。它将L说明为A和B的虚基类。2021-9-193当在多条继承路径上有一个公共的基类,在这些路径中的某几条路经汇合处,这个公共基类
3、就会产生多个实例。如果只想保存这个基类的一个实例,可以将这个公共基类说明为虚拟基类或称虚基类。它仅是简单地将关键字virtual加到基类的描述上,例如改写上述例子为例5-202021-9-194例5-20或classA:public或classA:publicvirtualLclassLvirtual{public:intnext;};classA:virtualpublicL{…这时C类对象中只有L的一个复制,因而函};数C::f()中的语句classB:virtualpublicLnext=0;没有二义性。
4、{};对于类C而言,L类classC:publicA,publicB是B类的虚基类,而是{类A的真基类;但对于public:类B而言,L类还是Bvoidf(){next=0;}类的真基类。};例5-21classL{…public:intnext;…};classA:virtualpublicL此例中,对于类C而言,{…L类是A类的虚基类,};而是类B的真基类。classB:virtualpublicL{…};classC:publicB,publicA{派生时,A,B的顺序变了public:voidf(){n
5、ext=0;}};一个派生类的对象的地址可以直接赋给虚基类的指针,例如:Cobj;L*ptr=&obj;这时不需要强制类型转换,并且,一个虚基类的引用可以引用一个派生类的对象,例如:Cobj2;L&ref=obj2;反之则不行,无论在强制类型转换中指定什么路径,一个虚基类的指针或引用不能转换为派生类的指针或引用。例如:C*P=(C*)(A*)ptr;将产生编译错误。2021-9-1972.虚基类对象的初始化虚基类的初始化与多继承的初始化在语法上是一样的,但隐含的构造函数的调用次序有点差别。虚基类构造函数的调用次
6、序是这样规定的:1.虚基类的构造函数在非虚基类之前调用。2.若同一层次中包含多个虚基类,虚基类构造函数按它们说明的次序调用。3.若虚基类由非虚基类派生,则遵守先调用基类构造函数,再调用派生类构造函数的规则。2021-9-198例如:classX:publicY,virtualpublicZ{}Xone;将产生如下调用次序:Z()Y()X()这里Z是X的虚基类,故先调用Z的构造函数,再调用Y的构造函数,最后才调用派生类X自己的构造函数。例5-222021-9-199#include"iostream.h"当建立对
7、象view时,classbase将产生如下调用次序:{public:base(){cout<<"Base"<8、:public用bas顺e2序,为virt:ualpublicbase{public:level2(){cout<<"level2"<
8、:public用bas顺e2序,为virt:ualpublicbase{public:level2(){cout<<"level2"<
此文档下载收益归作者所有