继承中的二义性 虚继承 virtual关键字

乍听虚继承,吓倒很多人!!

或许很多人会认为这和虚函数有关,其实,几乎没有任何关系。它的出现,是为了克服继承中一个非常棘手的问题,也就是臭名昭著的菱形继承(二义性)问题。

二义性,也就是说,假如我们有一个基类:

class Dog //狗,虚基类

{

public:

    int getWeight()

{

    return m_nWeight;

}

protected:

int m_nWeight;

};

class OrientDog : public Dog //东方的狗,继承自Dog

{

};

class WhiteDog : public Dog //白狗,继承自Dog

{

};

class myDog : public OrientDog, public WhiteDog //我的狗,是一条东方的白狗

{

public:

    myDog(int weight)

    {

        m_nWeight = weight; //error C2385: 'myDog::m_nWeight' is ambiguous

    }

};

在我们编译的时候,会发现myDog的构造函数,无法编译通过。编译器说:myDog::m_nWeight这个成员变量不能唯一确定。

为什么?

这就是由于多重继承所带来的二义性,其实也就是所谓的菱形继承。下面是继承图:

         Dog

         / \

OrientDog   WhiteDog

         \ /

        myDog

这样的继承结构,导致myDog重复继承了基类Dog的数据成员m_nWeight以及非虚的成员函数getWeight(),也就是说,在派生类myDog里,存在了两个m_nWeight成员变量和两个getWeight()成员函数,从而myDog无法辨认哪个到底应该是正统的,正所谓一山容不得二虎,我们必须要想个办法,把这种混乱不堪的行为整顿一下。

怎么办?

快刀斩乱麻,告诉编译器,在遇到这样的情况时,只选择第一个出现的成员就可以了,剔除掉以后所有的,从而就引进了虚拟继承的机制。也就是在继承属性前加上关键字virtual,就可以轻松的办到这一切。现在,我们重写OrigentDog和WhiteDog这两个中间类:

class OrientDog : virtual public Dog //东方的狗,继承自Dog

class WhiteDog : virtual public Dog //白狗,继承自Dog

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值