读书人

关于虚继承中成员偏移量的诡异有关问题

发布时间: 2012-03-15 11:50:38 作者: rapoo

关于虚继承中成员偏移量的诡异问题
class base
{
public:
int data;
};

class der1:virtual public base
{
public:
int data1;
virtual void f(){}
};

class der2:virtual public base
{
public:
int data2;
};

class der3:public der1,public der2
{
public:
int data3;
};


//程序代码:
printf("&data= %p\n", &der3::data);//0x0
printf("&data1= %p\n", &der3::data1);//0x8
printf("&data2= %p\n", &der3::data2);//0x4
printf("&data3= %p\n", &der3::data3);//0x14

使用VC2005,输出分别为0,8,4,0x14,我已知der3的对象布局如下:
vftable
vbtable
data1
vbtable
data2
data3
data
上图上每项都是4字节,一共是28字节,那么这些偏移是怎么算出来的呢?


[解决办法]
虚表结构?
[解决办法]
这个一时半会也说不清楚,推荐看lippman的“深度探索c++对象模型”
里面讲得很详细。
[解决办法]
这是因为,&der3::data等并不是数据成员在der3中的位置,而是数据成员在各自所属类中的位置,因此
&der3::data == &base::data
&der3::data1 == &der1::data1
&der3::data2 == &der2::data2
[解决办法]
谁能给出一个这三个编译器都符合的解释

g++ 4 结果
&data= 00000000
&data1= 00000004
&data2= 00000004
&data3= 00000010
C++builder 结果
&data= 00000001
&data1= 00000009
&data2= 00000005
&data3= 00000015

[解决办法]
和编译器相关的东西


[解决办法]
我看了一下这几个类的大小,和编译得到的结果,得出了这个规律:

忽略编译器给每个类分配的地址的顺序,如ls诸位所言,顺序的分配和编译器有关。

然后,你可以试着算一下编译器给类分配的地址的差值,发现
base:4Bytes
der1:12Bytes
der2:4Bytes
der3:当然没法计算了,呵呵

但是根据前面的这三个类,可以看出,这个时候编译器只分配了虚表结构的指针的大小,并没有给data数据段分配。


以上是我的理解,请各位批评指正!
[解决办法]
知道其组成就行啦
去研究那些好像没什么必要

[解决办法]
不同的编译器都有自己的处理方法。

而&der3::data这样取类成员变量的地方,只是这个变量在类中的相对位置了,一般说,同一个访问权限块里的变量的位置是顺序的,其它的就要看编译器的处理方法了。

读书人网 >C++

热点推荐