C++对象模型(二)多继承

来源:互联网 发布:java教材 pdf 编辑:程序博客网 时间:2024/06/03 08:40

3.多继承模型
看下面代码:

class Base1{public:    Base1():_b1(1)    {}    virtual void fun1()    {        cout<<"Base1::fun1()"<<endl;    }    virtual void fun2()    {        cout<<"Base1::fun2()"<<endl;    }private:    int _b1;};class Base2{public:    Base2():_b2(2)    {}    virtual void fun3()    {        cout<<"Base2::fun3()"<<endl;    }    virtual void fun4()    {        cout<<"Base2::fun4()"<<endl;    }private:    int _b2;};class Derive:public Base1,public Base2{public:    Derive():_d(3)    {}    virtual void fun2()    {        cout<<"Derive::fun2()"<<endl;    }    virtual void fun4()    {        cout<<"Derive::fun4()"<<endl;    }    virtual void fun5()    {        cout<<"Derive::fun5()"<<endl;    }private:    int _d;};int main(){    Base1 b1;    Base2 b2;    Derive d;    cout<<sizeof(d)<<endl;//20    return 0;}

这里d的大小为什么是20呢,下面给出d的对象模型:
这里写图片描述
看下内存:
这里写图片描述

用下面函数打印之:(注:VS2008环境)

void test(){    Derive d;    pfun* p = (pfun*)*((int*)(&d));    PrintVirtual(p);    p-=4;    PrintVirtual(p);}

这里写图片描述

多重继承编译器是怎么做的呢?
1)先将基类的虚表中的内容各自拷贝一份,有几个基类,就有几个虚表
2)如果派生类对基类中的虚函数进行重写,就是用派生类中的虚函数替换相同偏移位置的基类虚函数
3)派生类将自己新增的虚函数放在第一个基类虚表后面

4.含虚继承的多继承(菱形继承)

class Base{public:    Base():_b(1)    {}    virtual void fun1()    {        cout<<"Base::fun1()"<<endl;    }private:    int _b;};class C1:public virtual Base{public:    C1():_c1(2)    {}    virtual void fun2()    {        cout<<"C1::fun2()"<<endl;    }    virtual void fun3()    {        cout<<"C1::fun3()"<<endl;    }private:    int _c1;};class C2:public virtual Base{public:    C2():_c2(3)    {}    virtual void fun4()    {        cout<<"C1::fun4()"<<endl;    }    virtual void fun5()    {        cout<<"C1::fun5()"<<endl;    }private:    int _c2;};class Derive:public C1,public C2{public:    Derive():_d(4)    {}    virtual void fun3()    {        cout<<"Derive::fun3()"<<endl;    }    virtual void fun5()    {        cout<<"Derive::fun5()"<<endl;    }    virtual void fun6()    {        cout<<"Derive::fun6()"<<endl;    }private:    int _d;};int main(){    cout<<sizeof(Derive)<<endl;//36    return 0;}

下面给出Derive的对象模型:
这里写图片描述
用下面函数打印验证之:

void test(){    Derive d;    pfun* p = (pfun*)*((int*)(&d));    PrintVirtual(p);    p-=4;    PrintVirtual(p);    p-=3;    PrintVirtual(p);}

这里写图片描述
C1,C2的虚表生成机制和前面类似多继承一样。
菱形虚拟继承派生类虚表:
1)覆盖基类的的虚函数
2)如果派生类新增虚函数,则新增添到虚表后面