探索c++多态对象模型

一、探索虚函数表
虚函数表是通过一块连续内存来存储虚函数的地址。这张表解决了继承、虚函数(重写)的问题。在有虚函数的对象实例中都存在一张虚函 数表,虚函数表就像一张地图,指明了实际应该调用的虚函数函数。

测试代码:

class Base
{
public : 
     void func1()
    {
        cout<<"Base::func1" <<endl;
    }

    virtual void func2()
    {
        cout<<"Base::func2" <<endl;
    }

private :
    int a;
};

class Derive :public Base
{
public :
     void func1()
    {
        cout<<"Derive::func1" <<endl;
    }

    virtual void func3()
    {
        cout<<"Base::func3" <<endl;
    }

    int _d;
};
void main()
{
    Base* p1 = new Base;
    Base* p2 = new Derive;

    cout<<sizeof(Base)<<endl;
    cout<<sizeof(Derive)<<endl;

    p1->func1();
    p2->func1();
}

虚表:
存放虚函数
这里写图片描述

多态原理:
这里写图片描述
二、探索单继承对象模型

由于编译器优化问题,第三个地址将不会打出,所以需要手动打印
手动打印地址:


typedef void(*VFUNC)();

void PrintVTable(int** vtable)
{
    printf("vtable:0x%p\n", vtable);
    for (size_t i = 0; vtable[i] != 0; ++i)
    {
        printf("vfunc[%d]:0x%p->", i, vtable[i]);
        VFUNC f = (VFUNC)vtable[i];
        f();
    }
    cout<<endl;
}
void main()
{/*
    Base* p1 = new Base;
    Base* p2 = new Derive;

    cout<<sizeof(Base)<<endl;
    cout<<sizeof(Derive)<<endl;

    p1->func1();
    p2->func1();*/

    Base b1;
    Derive d1;

    PrintVTable((int**)(*(int**)&b1));
    PrintVTable((int**)(*(int**)&d1));
    system("pause");
}

这里写图片描述
这里写图片描述
三、探索多重继承的内存布局
代码:

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 d1 ;
};

typedef void(*VFUNC)();

void PrintVTable(int* vtable)
{
    printf("vtable:0x%p\n", vtable);
    for (size_t i = 0; vtable[i] != 0; ++i)
    {
        printf("vfunc[%d]:0x%p->", i, vtable[i]);
        VFUNC f = (VFUNC)vtable[i];
        f();
    }
    cout<<endl;
}

int main()
{
    Base1 b1;
    Base2 b2;
    Derive d1;

    PrintVTable((int*)(*(int*)&b1));
    PrintVTable((int*)(*(int*)&b2));

    PrintVTable((int*)(*(int*)&d1));
    PrintVTable((int*)(*((int*)((int)&d1+sizeof(Base1)))));
}

这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/adzn1/article/details/80045790