大家好,欢迎来到IT知识分享网。
1、虚基类的引入
我们再来复习一下“多重继承的对象布局”,假设继承的类结构是这样的:
相应的代码:
class W { public: int i_w; }; class X : public W {}; class Y : public W {}; class Z : public X, public Y {};
我们在main()函数中加入如下代码:
Z z; cout << z.i_w << endl; //这句话编译会报错
系统提示i_w的访问不明确。为什么呢?
因为定义Z对象时,W类会被继承2次,1次是Z –> X –> W,1次是Z –> Y –> W。虚基类的提出就是为了解决这种重复继承的问题,让W类只被继承1次。
虚基类的代码如下:
class W { public: int i_w; }; class X : virtual public W {}; class Y : virtual public W {}; class Z : public X, public Y {};
2、虚基类表、虚基类表指针
我们把前面虚基类的代码修改一下:
using namespace std; class W { public: }; class X : virtual public W {}; class Y : virtual public W {}; class Z : public X, public Y {}; int main() { cout << sizeof(W) << endl; cout << sizeof(X) << endl; cout << sizeof(Y) << endl; cout << sizeof(Z) << endl; }
输出如下:
为什么输出的结果是:1、4、4、8呢?
这里要引入2个概念:1、虚基类表 vbtable 2、虚基类表指针 vbptr。
虚基类表指针占4个字节,类X、Y各含1个虚基类表指针,类Z继承这2个虚基类表指针,所以Z对象占8个字节。
3、虚基类中的对象数据布局
为了更好地观察虚基类中的对象数据布局,我们往每个类中都增加1个成员变量。
class W { public: int i_w; }; class X : virtual public W { public: int i_x; }; class Y : virtual public W { public: int i_y; }; class Z : public X, public Y { public: int i_z; };
(1) cl /d1 reportSingleClassLayoutX ch08.cpp
虚基类表指针占4个字节,i_x占4个字节,i_w占4个字节,所以类X的对象占12个字节。
类X对象数据布局:
(2) cl /d1 reportSingleClassLayoutY ch08.cpp
类Y对象的数据布局跟类X对象类似。
(3) cl /d1 reportSingleClassLayoutZ ch08.cpp
类Z对象数据布局:
4、虚基类带虚函数时的对象布局
4.1 类W有虚函数(其他类都没虚函数)
virtual void w_h() { cout << "W::w_h()" << endl; }
这时类X的对象成员布局是这样的:
类Z的对象成员布局是这样的:
从图中可以看到,这个时候虚函数表指针vptr在子对象w的头部。
4.2 类X有虚函数(类W、X都有虚函数)
virtual void x_h() { cout << "X::x_h()" << endl; }
这时类X的对象成员布局是这样的:
类Z的对象成员布局是这样的:
4.3 类Z有虚函数 (类W、X也有虚函数)
virtual void z_h() { cout << "Z::z_h()" << endl; }
这时的对象成员布局和4.2中一样:对象Z和X共用同一个虚函数表指针。
4.4 类Z有虚函数(其他类都没虚函数)
此时Z类对象的对象布局如下:
从上面的结果看,虚基类的对象布局有如下规律:
(1)在孙子类Z的对象布局中,爷爷类(W类)的数据总是位于最后位置。
(2)父类X、Y都有一个虚基类表指针。
(3)仅爷爷类W有虚函数时,它的虚函数表指针在W类对象的头部。
(4)仅X或Y类有虚函数时,虚函数表指针就在X或W类对象的头部;在Z类对象中,虚函数表指针也位于对象的头部。
比如当Y有虚函数,其他类都没有虚函数时,类Z对象的对象布局如下:
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/137708.html