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

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)如果派生类新增虚函数,则新增添到虚表后面

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章