C++中:类数据成员的内存布局

首先我们从一个有趣的问题引入:  

class A  { };

当我们运行 :cout<<"sizeof(A)"<<endl;会惊奇的发现,j结果不是0,而是1;

为啥会是这样呢?其实在《深度探索C++对象模型》一本书中,有详细的解读,我在这只想说说自己的理解:首先class A 是一个类型,是用来实例化对象的,所以它就必须有具体的空间,使系统能按照它的格式分配内存。

如果  A   a; 当然sizeof(a)的结果也是1。这个是因为它是以一个对象存在的,我们必有有一个空间(地址)能够让我们的程序找到它。

所以让我们再返回书中描述,在这种情况下,编译器为我们自动插入一个 char 以满足能够占用内存的效果。

class A{   int   a;  char  c;  };

class B :public virtual  A { };

class C :public virtual A { };

class D:public  B ,public  C { };

下面是调试代码:

#include<iostream>
using namespace std;
class A{  
	      int   a; 
              char  c; 
};
class B :public virtual  A { };
class C :public virtual A { };
class D:public  B ,public  C { };
 
int main(void)
{
	cout<<sizeof(A)<<endl;
	cout<<sizeof(B)<<endl;
	cout<<sizeof(C)<<endl;
	cout<<sizeof(D)<<endl;
	return 0; 
}

上面结果 :  8   12   12   16    

C++在类的数据成员布局上有几个因素:

1: 语言本身所造成的负担。

   当语言支持virtual base class 时,就会产生一些类似vptr的额外指针,会是类的内存空间扩大。上面的例子就是 B  C 没有添加任何数据成员,只是virtual的继承了A,他们的内存就扩大了4 (一个指针的容量)。理解这块,可以和vptr 联系起来,类似。

2:Alignment (内存对对齐)。 

这个类似于C语言中struct中的内存对齐,及异质数据组合,编译器会为了CUP读去数据的效率而做一些优化。即 字节对齐。

有关内存对齐的问题可以参考这篇文 :

http://blog.csdn.net/trageday_motata/article/details/20637509

由于内存对齐的原因,A的值为8. 在继承过程中,派生类的大小是在基类的基础上增加自己添加的空间,B 和C添加了一个类似vptr的指针,所以是12.

那么,D为啥是16呢,按照添加的原理,不是应该是12+12=24 为啥是16呢,这就是c++中虚继承的缘故,虚继承就是为这种,多重派生类中可能会存在多个基类的副本而提出的。即12+12-8=16 减去一个A的副本就是本来D的空间大小。

另外,我们如果把calss  A  改一下:

class A{  
	      int   a; 
	      char  c; 
	      virtual void fun()=0; 
};
这是的结果会是:12 ,因为有了虚函数,编译器就会为每一个类的对象分配一个vptr,用来指向自己的虚函数表 virtual  table





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值