C++对象模型——1.没有继承结构的类布局

注: 64位VS下测试的结果,g++的实现可能不一样

#include <iostream>
using namespace std;

class A {
public:
    int a;
    virtual ~A() {
        a = 0;
    }
};

int main()
{
    A* pa = new A();
    cout << sizeof(A) << endl;
    delete pa;
    return 0;
}

输出

16
VS监视中pa的值

通过监视窗口可以看到pa指向的内存包含了两个成员:__vfptr和a。
__vfptr是个指针,指向一个数组。

A的对象模型为:

成员 对象内起始位置 占用字节
__vftpr 0 8
a 8 4
(对齐补充) 12 4

__vfptr存储的是A的虚表的地址,这个虚表目前只有一项,存储的是A的虚析构函数的地址~A。

为什么sizeof(A) == 16 而不是12?
因为默认情况下,编译器要保证通过数组方式访问A的成员的时候也是高效的,不管是隐式的__vfptr还是显式的a。
当按照如上所示布局的时候,读取__vfptr和a只需要一个周期。即使是访问A的数组中的成员的时候也是这样的。
但是如果按照12字节对齐,第二个A对象的__vfptr的地址就不是8字节对齐,访问__vfptr的时候,需要读取16字节,然后获取中间的8个字节。同样的汇编代码,但是系统会做更多的事情。效率自然低一些。

__vfptr是编译器在类中添加的成员,对程序员透明的。
当类中有虚函数,包括从基类继承的虚函数时,__vfptr都会存在,具体__vfptr的位置和数量跟类的继承结构有关系。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容