探索多态模型—菱形继承和菱形虚拟继承

菱形继承
类AA被类BB和类CC重复继承:

这里写图片描述

class AA
{
public:
    virtual void a(){ cout << "AA::a()" << endl; }
    virtual void a1(){ cout << "AA::a1()" << endl; }
public:
    int _a;
};

class BB : public AA
{
public:
    virtual void a(){ cout << "BB::a()" << endl; }
    virtual void a2(){ cout << "BB::a2()" << endl; }
    virtual void a3(){ cout << "BB::a3()" << endl; }
public:
    int _b;

};

class CC : public AA
{
public:
    virtual void a(){ cout << "CC::a()" << endl; }
    virtual void a1(){ cout << "CC::a1()" << endl; }
    virtual void a4(){ cout << "CC::a4()" << endl; }
public:
    int _c;

};

class DD : public BB , public CC
{
public:
    virtual void a(){ cout << "DD::a()" << endl; }
    virtual void a2(){ cout << "DD::a2()" << endl; }
    virtual void a3(){ cout << "DD::a3()" << endl; }
    virtual void a5(){ cout << "DD::a5()" << endl; }
public:
    int _d;
};

typedef void(*FUNC) ();

void Print(int *Vfptr)
{
    cout << "虚表地址" << Vfptr << endl;
    for (int i = 0; Vfptr[i] != 0; ++i)
    {
        FUNC f = (FUNC)Vfptr[i];
        cout << "[" << i << "]" << endl;
        f();
    }
    cout << endl;
}
int main()
{
    DD d;
    int *Vfptr1 = (int*)(*(int*)&d);
    int *Vfptr2 = (int*)(*((int*)&d+sizeof(BB)/4));
    Print(Vfptr1);
    Print(Vfptr2);
    system("pause");
    return 0;
}

虚表的结果:

这里写图片描述

菱形继承总结:

会出现数据冗余和二义性问题
派生类会分别继承每个基类的虚函数表,并将自己的虚函数放在第一个虚函数表中
成员变量的顺序按照继承的关系排列

菱形虚拟继承
虚继承就是在类BB和类CC继承的时候加上virtual关键字

class AA
{
public:
    virtual void a(){ cout << "AA::a()" << endl; }
    virtual void a1(){ cout << "AA::a1()" << endl; }
public:
    int _a;
};

class BB : virtual public AA
{
public:
    virtual void a(){ cout << "BB::a()" << endl; }
    virtual void a2(){ cout << "BB::a2()" << endl; }
    virtual void a3(){ cout << "BB::a3()" << endl; }
public:
    int _b;

};

class CC : virtual public AA
{
public:
    virtual void a(){ cout << "CC::a()" << endl; }
    virtual void a1(){ cout << "CC::a1()" << endl; }
    virtual void a4(){ cout << "CC::a4()" << endl; }
public:
    int _c;

};

class DD : public BB , public CC
{
public:
    virtual void a(){ cout << "DD::a()" << endl; }
    virtual void a2(){ cout << "DD::a2()" << endl; }
    virtual void a3(){ cout << "DD::a3()" << endl; }
    virtual void a5(){ cout << "DD::a5()" << endl; }
public:
    int _d;
};

typedef void(*FUNC) ();

void Print(int *Vfptr)
{
    cout << "虚表地址" << Vfptr << endl;
    for (int i = 0; Vfptr[i] != 0; ++i)
    {
        FUNC f = (FUNC)Vfptr[i];
        cout << "[" << i << "]" << endl;
        f();
    }
    cout << endl;
}
int main()
{
    DD d;
    int *Vfptr1 = (int*)(*(int*)&d);
    int *Vfptr2 = (int*)(*(int*)((char*)&d+sizeof(DD)-sizeof(AA)));
    int *Vfptr3 = (int*)(*((int*)((char*)&d + sizeof(BB)-sizeof(AA))));

    Print(Vfptr1);
    Print(Vfptr2);
    Print(Vfptr3);

    system("pause");
    return 0;
}

这里写图片描述

注:当类BB,类CC都对类AA中的虚函数a()进行覆盖,会编译出错,出现二义性问题。这时类DD需要对虚函数a()进行重写,才可避免。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值