C++类的空间分配

代码如下:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 class A
 5 {
 6     //char a;
 7 };
 8 class B:public virtual A
 9 {};
10 class C:public virtual A
11 {};
12 class D:public B,public C
13 {};
14 int main()
15 {
16     cout<<"sizeof(A)="<<sizeof(A)<<endl;
17     cout<<"sizeof(B)="<<sizeof(B)<<endl;
18     cout<<"sizeof(C)="<<sizeof(C)<<endl;
19     cout<<"sizeof(D)="<<sizeof(D)<<endl;
20     return 0;
21 }

运行结果:

我的编译器是vs2012

class A不含任何成员时:

    

class A含有一个成员变量char a时:

    

不同的机器及不同的编译器下结果很可能是不一样的。

首先说一下他们的大小受那些因素的影响:

1.C++语言本身

  当涉及到虚继承时,C++是通过某种形式的指针来实现的。比如说多态的实现就是通过查找虚函数表找到相应函数来实现的。

2.编译器优化

3.内存对齐

  将数值调整到某数的整数倍,以使bus的"运输量"达到最高效率。

 

现在来看我们的问题:

1、为什么A的大小为1?

  设想一下你写了这么句代码A  temp;如果A的大小为0的话,操作系统要如何为temp分配内存呢?不分配内存的话如何去找到temp在哪呢?所以为了让类的对象在内存里有一个独一无二的地址,编译器会向空类里插入1byte 的char。sizeof(A)就为1喽。

 

2、B和C的大小

由于是虚继承,B和C会包含一个指针,有4byte。加上从A继承的1byte,应该是5byte啊。这里就涉及到上述的第二个原因了,编译器优化。由于B和C已经是4byte了,那么不存在问题1中的问题了,那么这时候编译器就没有去加上A中的1byte。如果你的测试结果是5,那说明你的编译器没有做这个优化。

如果你的结果是8,又是怎么回事呢,这就又涉及到上述第三点原因了,所谓内存对齐,就是说将数值调整到某数的整数倍,以使bus的"运输量"达到最高效率。32位机器上,这个‘某数’通常为4,所以5个字节的大小就被调整成了4的2倍 = 8。

 

3、D的大小

看第二幅图中,B=5,C=5,为什么D的大小不是5+5=10呢?

因为一个virtual base class subobject只会在 derived class中存在一份实体,不管它在class继承体系中出现了多少次。所以A的大小是1(A的大小)+4(B中除去A部分的大小)+4(C中除去A部分的大小) = 9。

posted @ 2015-03-29 18:28  momo_Unique  阅读(923)  评论(0编辑  收藏  举报