C++::探索对象模型

前面我们已经知道, 在没有虚函数的时候, 对象的大小就是对应的成员变量的大小, 而成员函数不会占用对象的空间, 今天我们来讨论一下, 当类中定义了虚函数的时候, 此时对象的大小以及对象模型

非继承下的对象模型

class Base
{
public:
    virtual void func1()
    {
        cout << "Base::func1()" << endl;
    }
    virtual void func2()
    {
        cout << "Base::func2()" << endl;
    }
private:
    int a;
};
void Test1()
{
    Base b1;
}

此时打开编译器, 观察 b1 的对象模型如下图所示
这里写图片描述
此时我们会发现对象b1 它除了有一个成员变量 a 之外, 它还有一个虚函数表, 这个虚函数表的数据结构是由一个指针数组来维护的, 这个指针数组中存放了指向虚函数的指针, 并且指向虚函数指针的结束标识在VS下是以一个0为结束标识, 也就是说 b1的对象模型如下图所示
这里写图片描述

单继承下的对象模型

class Base
{
public:
    virtual void func1()
    {
        cout << "Base::func1()" << endl;
    }
    virtual void func2()
    {
        cout << "Base::func2()" << endl;
    }
private:
    int a;
};

class Derive :public Base
{
public:
    virtual void func1()
    {
        cout << "Derive: func1()" << endl;
    }
    virtual void func3()
    {
        cout << "Derive: func3()" << endl;
    }
    virtual void func4()
    {
        cout << "Derive: func4()" << endl;
    }
private:
    int b;
};

typedef  void(*VFUNC)();

void PrintVTable(int* VTable)
{
    cout << "虚表地址: " << VTable << endl;
    int i = 0;
    for(; VTable[i] != 0; i++)
    {
        printf("第 %d 个虚函数地址: 0x%x -> ", i, VTable[i]);
        VFUNC f = (VFUNC)VTable[i];
        f();
    }
    cout << endl;
}

void Test1()
{
    Base b1;
    Derive d1;
    int*VTable1 = (int*)(*(int*)(&b1));
    int*VTable2 = (int*)(*(int*)(&d1));

    PrintVTable(VTable1);
    PrintVTable(VTable2);
}

为了方便起见, 我们将对应的虚表打印出来, 此时会发现如下现象
这里写图片描述
接下来探索一下对应的 b1 和 d1 的对象模型
这里写图片描述
这里写图片描述

多继承对象模型

class Base1
{
public:
    virtual void func1()
    {
        cout << "Base1::func1()" << endl;
    }
    virtual void func2()
    {
        cout << "Base1::func2()" << endl;
    }
private:
    int b1;
};

class Base2
{
public:
    virtual void func1()
    {
        cout << "Base2::func1()" << endl;
    }
    virtual void func2()
    {
        cout << "Base2::func2()" << endl;
    }
private:
    int b2;
};
class Derive :public Base1, public Base2
{
public:
    virtual void func1()
    {
        cout << "Derive: func1()" << endl;
    }
    virtual void func3()
    {
        cout << "Derive: func3()" << endl;
    }
private:
    int b;
};

此时的对象模型如下图所示
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_41027326/article/details/81109611