C++ 类大小计算详解:内存对齐与虚函数机制
这是一个经典的 C++ 面试题,也是理解对象内存布局的关键。很多人直觉认为类的大小等于所有成员变量之和,但实际上编译器会根据内存对齐、虚函数表指针以及继承关系进行自动调整。

核心规则速览
在动手计算之前,先明确几个基本原则:
- 非静态成员变量是构成类大小的主体。
- 静态成员变量存储在数据区,不属于对象实例,
sizeof时不计入。 - 成员函数存储在代码段,同样不计入对象大小。
- 虚函数:只要类中存在虚函数(包括继承而来的),对象内部就会包含一个虚函数表指针(vptr)。64 位系统通常为 8 字节,32 位为 4 字节。
- 内存对齐:为了 CPU 访问效率,成员之间或末尾会有填充字节。
- 第一个成员偏移量为 0。
- 后续成员需位于其自身大小整数倍的地址上。
- 最终类总大小必须是最大成员对齐数的整数倍。
- 空类:大小为 1 字节,确保每个对象拥有唯一地址。
详细计算示例
1. 基础情况:空类
class Empty {
// 没有任何成员
};
虽然看起来什么都没有,但 sizeof(Empty) 的结果是 1 字节。这是为了给对象分配一个独一无二的内存地址,避免不同对象占据同一位置。
2. 只有成员变量(注意对齐)
class Example1 {
char c; // 1 字节
int i; // 4 字节
};
直观上看是 1 + 4 = 5 字节,但实际结果是 8 字节。原因如下:
c从偏移 0 开始,占 1 字节。i需要 4 字节对齐,所以它不能紧挨着c(偏移 1),必须跳到偏移 4 的位置。- 中间产生了 3 字节的填充。
- 当前占用:1(
c) + 3(填充) + 4(i) = 8 字节。 - 最大对齐数是 4,8 是 4 的倍数,无需末尾填充。
3. 引入虚函数(vptr 的影响)
class {
a;
{}
};


