概述
我们都知道类中包含着数据成员,但是数据成员在内存中是怎样分布的呢?继承之后数据又是怎样布局的呢?下面对这些问题进行整理解答。首先说明的是类的空间分布是编译器编译的结果,不同的编译器有可能会不一样,但是原理是一样的。
1、空类
我们定义了一个空类,然后对空类进行sizeof计算,如下:
class myclass
{
};
cout << sizeof myclass << endl; //打印出1
按照正常的逻辑,这里应该为0啊,为什么会为1呢?
因为编译器在我们背后搞鬼,在我们定义空类后,编译器会安插一个char到类中。这样这个类定义出来的两个对象在内存中就是独一无二的。
2、数据成员的分布
C++标准要求,在同一个防控属性(private、protect、public)中,非静态数据变量在对象中的排列顺序和声明顺序一样。静态成员变量会存放在数据模块中,不会放在对象布局中,和类对象无关。
对象的成员变量初始化的顺序是由声明顺序决定就是这样来的。
数据与数据之后并不一定是连续空间,因为有 边界调整(对齐补齐)的原因会填补一些字节。如
class myclass
{
char m_char; //占1个字节
int m_iNum; //占4个字节
short m_iport; //占2个字节
};
cout << sizeof myclass << endl;
输出的结果为12,内存占用如下图所示:
每个方格代表一个字节,黄色的代表填补字节。
编译器为了支持对象模型,有时会合成一些内部使用的数据成员,如vptr(指向虚函数表的指针)。