贝利信息

c++类的内存布局 c++对象模型初探【核心】

日期:2026-01-03 00:00 / 作者:穿越時空
C++类内存布局由编译器严格决定:单一继承时基类在前、成员按序排列;含虚函数则对象首部有vptr指向vtable;多重继承中非最左基类需this偏移;虚继承引入vbptr和动态偏移,增加开销。

在 C++ 中,类的内存布局不是黑箱,而是由编译器依据标准和实现细节严格决定的。理解它,是掌握多态、继承、虚函数调用、指针偏移等底层行为的关键——它直接决定了 this 指针的值、static_castreinterpret_cast 的安全性,以及为什么某些对象不能简单 memcpy。

单一继承下的内存布局:数据成员顺序即内存顺序

非虚继承时,子类对象内存中依次排布:基类部分(按继承顺序)、自身成员变量(按声明顺序)。没有额外开销,也没有“间隙”(除非对齐要求插入填充字节)。

虚函数表(vtable)与虚函数指针(vptr)的位置

含虚函数的类,编译器会在对象最前面插入一个隐式的 vptr(通常为指针大小,如 8 字节),指向全局只读的虚函数表(vtable)。vtable 本身不存于对象内,而是编译期生成的静态数据结构。

多重继承与指针调整:this 指针不再是简单的地址

当一个类从多个非虚基类继承时,各基类子对象在内存中并列排布。访问不同基类接口时,this 指针需做偏移调整——这由编译器在调用虚函数或进行 static_cast 时自动插入加减指令完成。

虚继承:解决菱形继承歧义,引入虚基类指针(vbptr)

虚继承使共享基类只出现一次。为此,派生类中会添加 vbptr(指向虚基类表),并在运行时动态计算虚基类子对象的偏移。这带来额外空间与时间开销。