虚继承与普通继承之间的关系

首先,重复一下虚拟继承与普通继承的区别有:

假设derived 继承自base类,那么derived与base是一种“is a”的关系,即derived类是base类,而反之错误;

假设derived 虚继承自base类,那么derivd与base是一种“has a”的关系,即derived类有一个指向base类的vptr。

因此虚继承可以认为不是一种继承关系,而可以认为是一种组合的关系。因为虚继承有着“继承”两个关键字,那么大部分人都认为虚继承与普通继承的用法没什么太大的不同。由此用在继承体系中,这种将虚继承认为是普通继承的危害更佳大。下面先用一个例子来说明问题:

    class base  
    {  
    public:  
        base(){cout<<"base::base()!"<<endl;}  
        void printBase(){cout<<"base::printBase()!"<<endl;}  
    };  
      
    class derived:public base  
    {  
    public:  
        derived(){cout<<"derived::derived()!"<<endl;}  
        void printDerived(){cout<<"derived::printDerived()!"<<endl;}  
    };  


上面是普通继承实现,在实际应用中,我们可以使用下面的代码进行类型转换:


    int main(int argc, const char * argv[])  
    {  
        derived oo;  
        base oo1(static_cast<base>(oo));  
        oo1.printBase();  
        derived oo2 = static_cast<derived&>(oo1);  
        oo2.printDerived();  
        return 0;  
    }  


编译无错误,而且会得出正确的结果。其结果为:
 base::base()!
 derived::derived()!
 base::printBase()!
 derived::printDerived()!


而将上面的普通继承变成虚拟继承,如下代码:


    class base1  
    {  
    public:  
        base1(){cout<<"base::base()!"<<endl;}  
        void printBase(){cout<<"base::printBase()!"<<endl;}  
    };  
      
    class derived1:virtual public base1  
    {  
    public:  
        derived1(){cout<<"derived::derived()!"<<endl;}  
        void printDerived(){cout<<"derived::printDerived()!"<<endl;}  
    };  
      
    int main(int argc, const char * argv[])  
    {  
        derived1 oo;  
        base1 oo1(static_cast<base1>(oo));  
        oo1.printBase();  
        derived1 oo2 = static_cast<derived1&>(oo1);  
        oo2.printDerived();  
        return 0;  
    }  


编译上面的代码,提示如下:


可以看到不能将基类通过static_cast转换为继承类。我们知道c++提供的强制转换函数static_cast对于继承体系中的类对象的转换一般是可行的。那么这里为什么就不可以了呢?还是需要从虚拟继承的内部实现来说明问题。

virtual base class的原始模型是在class object中为每一个有关联的virtual base class加上一个指针vptr,该指针指向virtual基类表。有的编译器是在继承类已存在的virtual table直接扩充导入一个virtual base class table。不管怎么样由于虚继承已完全破坏了继承体系,不能按照平常的继承体系来进行类型转换。

不管怎么样,虚继承在类型转换是一定要十分注意。不要轻易使用虚继承,更不要在虚继承的基础上进行类型转换。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值