C++中添加float成员后类的大小为何未发生变化?
为什么添加float成员后C++类的大小没有变化?
嘿,这是个非常典型的内存对齐问题,我来帮你把背后的逻辑拆解清楚~
首先得纠正一个小误解:在64位系统中,int的大小通常是4字节(不是你以为的8字节),而虚函数表指针(vptr)是8字节,float同样是4字节。这是理解问题的关键。
我们来分别分析两种情况:
1. 注释掉float b时的类大小
此时类A的成员包括:
- 虚函数表指针(vptr):8字节(编译器自动添加,用于实现多态)
int a:4字节
根据C++的内存对齐规则:
- 每个数据成员会对齐到自身大小的整数倍(或编译器指定的对齐边界,这里是8字节)
- 类的总大小必须是其最大对齐成员大小的整数倍(这里最大的是vptr的8字节)
所以内存布局是:
- 0-7字节:vptr
- 8-11字节:
int a - 12-15字节:编译器自动填充的4字节(为了让总大小凑到8的倍数)
总大小就是16字节,和你看到的结果一致。
2. 取消注释float b后的类大小
此时类的成员变成:
- vptr:8字节
int a:4字节float b:4字节
计算总字节数:8+4+4=16,刚好是8的倍数(最大对齐成员的大小),所以不需要额外填充字节。布局变成:
- 0-7字节:vptr
- 8-11字节:
int a - 12-15字节:
float b
总大小自然还是16字节,这就是为什么你没看到变化的原因!
验证成员偏移量
你可以通过offsetof宏来查看每个成员的内存位置,更直观地理解布局:
#include <iostream> #include <cstddef> // 包含offsetof宏 class A { public: int a; float b; virtual void f(); }; int main() { std::cout << "sizeof(A): " << sizeof(A) << "\n"; std::cout << "Offset of vptr: 0\n"; std::cout << "Offset of a: " << offsetof(A, a) << "\n"; std::cout << "Offset of b: " << offsetof(A, b) << "\n"; return 0; }
运行后会输出:
sizeof(A): 16 Offset of vptr: 0 Offset of a: 8 Offset of b: 12
完全符合我们上面分析的布局~
总结一下:内存对齐是编译器优化内存访问效率的手段,它会让类的大小保持为最大对齐单元的整数倍,这就解释了添加float后大小不变的现象。
内容的提问来源于stack exchange,提问作者Prince Rambade
相关产品推荐
相关产品推荐

