首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

虚沿袭之后,类体中到底多了一些什么

2012-08-28 
虚继承之后,类体中到底多了一些什么?为了更好的理解虚继承,我想着通过查看类长度,来判断继承之后类中都是

虚继承之后,类体中到底多了一些什么?
为了更好的理解虚继承,我想着通过查看类长度,来判断继承之后类中都是包括多少内容。于是我想到了下面的程序:

C/C++ code
#include <iostream>using namespace std;class A{public:    int a;};class B1: public A{public:    int b1;};class B2: public A{public:    int b2;};class C:public B1,public B2{    int c;};void main(){    cout<<sizeof(A)<<endl;    //a        长度:4    cout<<sizeof(B1)<<endl;    //a,b1        长度:8    cout<<sizeof(B2)<<endl;    //a,b2        长度:8    cout<<sizeof(C)<<endl;    //a,a,b1,b2,c    长度:20}

运行结果我可以理解:
B1中有一个a的副本,B2中也是,多以导致类C中有两个a的副本,所以,如果在类C中想使用a的话,就会因为不确定a的值导致二义性
所以我又尝试了虚继承,也就是说类B1和类B2都是通过虚继承的方式从类A中继承过来的,也就是说:
C/C++ code
class B1:virtual public Aclass B2:virtual public A

其他不变,但是,当我这样写的时候,发现了B1、B2、C类体重都比原来还要大???输出结果是:
19 9 21
如果类C继承还是使用一个虚继承的话,如下两种方式:
C/C++ code
class C:virtual public B1, public B2class C: public B1,virtual public B2

输出结果是
19 9 24
如果从两个类中都是虚继承的话,如下:
C/C++ code
class C:virtual public B1,virtual public B2

输出结果就更大了,是:
1 9 9 28
求助大家,这到底是怎么回事啊?按理说,派生类C中应该只会有变量a的一个副本,这样说的话,应该会更小,怎么结果和我想的不一样呢?
谢谢!


[解决办法]
参考(编译器VS2010下,C的内存布局):
C/C++ code
    +--- 0    | {vbptr} 4    | c    +---    +--- (virtual base A) 8    | a    +---    +--- (virtual base B1)12    | {vbptr}16    | b1    +---    +--- (virtual base B2)20    | {vbptr}24    | b2    +---
[解决办法]
为了支持多态,根据目前的对象构造模型会在含有虚函数的类及其所有继承类中插入一个称作vptr的虚函数指针,所以会多出四个字节 无论你是否在继承类中对基类中的虚函数进行重新实现都会因为基类中存在虚函数而在所有的与那个基类相关的类中插入此指针项目,可以参见《深入理解C++对象模型》
[解决办法]
我在vs2010上执行如下代码
C/C++ code
class C:virtual public B1, public B2class C: public B1,virtual public B2
[解决办法]
1、真虚继承还是假虚继承?
2、一般就是:基类的所有数据 + 自身的数据 + 虚函数列表指针 + 自身维护的一个指针
[解决办法]
除了成员之外,肯定还要有个标志说明是这么继承的,所以肯定是大于16的,再加一个标志说明继承的先后关系,就是20,如果类型不一样,比如有char,float,就要考虑字节对齐

热点排行