多态之虚表剖析2

来源:互联网 发布:驱蚊软件下载 编辑:程序博客网 时间:2024/06/03 09:30

在一个既有虚继承又有虚函数的继承体系里,它的内存布局对象模型是怎么样的呢??

以菱形虚拟继承为例:

1、没有覆盖

如下代码:

#include <iostream>using namespace std;class B{public:    virtual void funtest1()    {        cout << "B::funtest1()" << endl;    }    int _b;};class C1:virtual public B{public:    virtual void funtest2()    {        cout << "C1::funtest2()" << endl;    }    int _c1;}; class C2:public virtual B{public:    virtual void funtest3()    {        cout << "C2::funtest3()" << endl;    }    int _c2;};class D :public C1, public C2{public:    void funtest4()    {        cout << "D::funtest4()" << endl;    }    int _d;};int main(){    D d;    cout << sizeof(d) << endl;    d._b = 1;    d._c1 = 2;    d._c2 = 3;    d._d = 4;    system("pause");    return 0;}

输出d对象的大小为36;

在vs2013下我们打开内存窗口并对其进行逐个分析如下:

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

通过类似方法不难得到d在内存中布局

这里写图片描述

进而得到这种情况的继承模型

2、有覆盖

将上代码稍加改造

class B{public:    virtual void test1()    {        cout << "B::test1()" << endl;    }    virtual void test2()    {        cout << "B::test2()" << endl;    }    int _b;};class C1:virtual public B{public:    virtual void test1() //重写B::test1()函数    {        cout << "C1::test1()" << endl;    }    virtual void test3()    {        cout << "C1::test3()" << endl;    }    virtual void test31()    {        cout << "C1::test31()" << endl;    }    int _c1;};class C2 :virtual public B{public:    virtual void test2()//重写B::test2()    {        cout << "C2::test2()" << endl;    }    virtual void test4()     {        cout << "C2::test4()" << endl;    }    int _c2;};class D :public C1, public C2{public:    void test5()    {        cout << "D::test5()" << endl;    }    int _d;};typedef void(*fun)();int main(){    D d;    cout << sizeof(d) << endl;    d._b = 1;    d._c1 = 2;    d._c2 = 3;    d._d = 4;       system("pause");    return 0;}

这里写图片描述

不难发现,和上模型相差不大,只不过覆盖的函数被放到了虚表中原来父类虚函数的位置。

虚函数表的指针存在于对象实例中最前面的位置(这是为了保证取到虚函数表的有最高的性能——如果有多层继承或是多重继承的情况下)

0 0