探究菱形继承对象模型

来源:互联网 发布:正在准备windows请不要 编辑:程序博客网 时间:2024/05/09 02:14

菱形继承

  • 定义及形式
    简单的理解就是同一个父类被两个不同子类继承,而这两个子类又被另一个新类同时继承,导致出现了一个类似菱形的继承体系,我们将其成为菱形继承。
    关于菱形继承的其他解释,我在上一博客中做了介绍(http://blog.csdn.net/haitang_yue/article/details/55211296),这里不做赘述。

    普通菱形继承

  • 代码
typedef void (*V_FUNC)();class AA{public:    virtual void f1()    {        cout<<"AA::f1"<<endl;    }public:    int _aa;};class BB:virtual public AA{public:    virtual void f1()    {        cout<<"BB::f1"<<endl;    }    virtual void f2()    {        cout<<"BB::f2"<<endl;    }public:    int _bb;};class CC:virtual public AA{public:    virtual void f1()    {        cout<<"CC::f1"<<endl;    }    virtual void f2()    {        cout<<"CC::f2"<<endl;    }public:    int _cc;};class DD:public BB,public CC{public:    virtual void f1()    {        cout<<"DD::f1"<<endl;    }    virtual void f3()    {        cout<<"DD::f2"<<endl;    }    virtual void f4()    {        cout<<"DD::f4"<<endl;    }public:    int _dd;};void PrintVTable (int* VTable){cout<<" 虚表地址>0x"<< VTable<<endl ;for (int i = 0; VTable[i ] != 0; ++i){V_FUNC f = (V_FUNC) VTable[i];f();}cout<<endl ;}int main(){    DD d;    d.BB::_aa = 0;    d.CC::_aa = 1;    d._bb = 2;    d._cc = 3;    d._dd = 4;    cout<<"DD";    int* VTable = (int*)(*(int*)&d );    PrintVTable(VTable);    cout<<"DD-CC";    VTable = (int*)(*((int*)&d+3) );    PrintVTable(VTable);    cout<<"DD-AA";    VTable = (int*)(*((int*)&d+7));    PrintVTable(VTable);    system("pause");    return 0;}
  • DD类对象模型

这里写图片描述

  • 对普通菱形继承时虚表的分析

这里写图片描述

  • 内存中的情况:

由于有两个父类,所以存在两个虚表

菱形虚拟继承

  • 简介
    为了解决菱形继承中二义性以及数据冗余所带来的缺点,通过使用虚拟继承用空间换时间的思想来解决问题。不过应注意,在我们平时的代码编写中,不到万不得已时最好不要使用菱形继承以及虚继承,因为这种结构所带来的效率问题很多。
  • 代码
class AA{public:    virtual void f1()    {        cout<<"AA::f1"<<endl;    }public:    int _aa;};class BB:virtual public AA{public:    virtual void f1()    {        cout<<"BB::f1"<<endl;    }    virtual void f2()    {        cout<<"BB::f2"<<endl;    }public:    int _bb;};class CC:virtual public AA{public:    virtual void f1()    {        cout<<"CC::f1"<<endl;    }    virtual void f3()    {        cout<<"CC::f3"<<endl;    }public:    int _cc;};class DD:public BB,public CC{public:    virtual void f1()    {        cout<<"DD::f1"<<endl;    }    virtual void f3()    {        cout<<"DD::f3"<<endl;    }    virtual void f4()    {        cout<<"DD::f4"<<endl;    }public:    int _dd;};typedef void (*V_FUNC)();void PrintVTable(int* VTable){    cout<<"虚表地址>0x"<< VTable<<endl ;    for (int i=0;VTable[i]!=0;++i)    {        V_FUNC f=(V_FUNC)VTable[i];        f();    }    cout<<endl ;}int main(){    DD d;    d._aa = 1;    d._bb = 1;    d._cc = 1;    d._dd = 1;    cout<<"DD";    int* VTable = (int*)(*(int*)&d );    PrintVTable(VTable);    cout<<"DD-CC";    VTable = (int*)(*((int*)&d+3) );    PrintVTable(VTable);    cout<<"DD-AA";    VTable = (int*)(*((int*)&d+7));    PrintVTable(VTable);    system("pause");    return 0;}
  • 运行结果
    运行结果

  • 内存分析
    内存分析

0 0