C++ 类大小计算:内存对齐、虚函数与继承详解
在 C++ 中,计算一个类的大小并不是简单地将成员变量的大小相加,而是涉及内存对齐、虚函数、继承等多个因素的影响。理解这些机制对于底层开发和性能优化至关重要。
核心规则
- 非静态成员变量是决定大小的主体。
- 静态成员变量属于全局数据区,不计入
sizeof。 - 成员函数存储在代码段,不计入
sizeof。 - 虚函数:只要类中有虚函数(包括继承来的),实例中就会包含一个虚函数表指针(vptr)。64 位系统下通常占 8 字节,32 位下占 4 字节。
- 内存对齐:编译器为了提高访问效率,会在成员之间或末尾填充字节,使变量存储在其倍数地址上,并使类总大小是最大对齐数的整数倍。
- 空类:大小为 1 字节,为了表示对象存在且拥有唯一地址。
详细示例分析
1. 基础情况:空类
class Empty {
// 没有任何成员
};
- 大小:1 字节
- 原因:编译器需要给这个类的对象分配一个独一无二的地址,所以会隐式插入 1 个字节。
2. 只有成员变量(考虑内存对齐)
class Example1 {
char c; // 1 字节
int i; // 4 字节
};
- 分析:
c从偏移 0 开始。i需要 4 字节对齐,因此必须从偏移 4 开始存放。这导致c后面有 3 个字节的填充。- 当前占用:1(c) + 3(填充) + 4(i) = 8 字节。
- 最大对齐数是 4,8 是 4 的倍数,无需末尾填充。
- 结果:8 字节(而不是直觉上的 1+4=5)。
3. 有虚函数(引入虚表指针)
class Base {
int a;
virtual void func() {}
};


