C++对象内存布局
类中的元素:类成员变量、类成员函数、静态成员变量、静态成员函数、虚函数、纯虚函数 。
影响对象大小的元素:类成员变量、虚函数表指针、虚基类指针、内存对齐。
注:所有的静态成员变量、静态成员函数、类成员函数都不会影响对象的大小,纯虚函数与虚函数一样都由虚函数表指针来管理。
_vftptr、_vbtptr的初始化由对象的构造函数, 赋值运算符自动完成;对象生命周期结束后,由对象的析构函数来销毁。
对象所关联的类型(type_info),通常放在virtual table的第一个slot中。_vftptr、_vbtptr的初始化由对象的构造函数, 赋值运算符自动完成;对象生命周期结束后,由对象的析构函数来销毁。
本测试使用的工具:

注:下述类中的成员变量均为int类型,由于类中的非虚成员函数都不影响对象的大小,因此类中涉及的成员函数均为虚函数。
- 单一类
- 空类:sizeof(CNULL) = 1
- 非空类:

sizeof(A) = 8
内存布局:

- 单一继承

sizeof(D) = 12
内存布局:

注:在单一继承中,子类中不含有虚函数表指针,它共享其基类的虚函数表指针。
- 多继承

sizeof(E) = 20
内存布局:

注:跟单一继承一样,子类中并不含有虚函数表指针(vfptr),它共享其继承的第一个基类的虚函数表指针。它继承的每个基类中都各自含有自己的虚函数表指针。
- 单一虚继承

sizeof(B) = 20
内存布局:

注:如果子类中的虚函数与基类中的虚函数完全相同,则子类中不再会存在vfptr指针。此类情况会影响子类对象的大小。
如果子类中的虚函数与基类中的虚函数不相同,则子类中也会存在vfptr指针,这是虚继承与非虚继承的区别,还有一点区别就是在虚继承中会存在vbptr指针。
虚表中第一个条目存放的是虚基类表指针到该类内存首地址的偏移量,第二、第三...个条目是该类的最左虚继承基类、次左虚继承基类...的内存地址相对于该类内存首地址的偏移量。
下面例子解释基类与子类虚函数相同时的情形:

sizeof(B) = 16
内存布局:


浙公网安备 33010602011771号