C++的菱形继承

        面向对象的三大基本特性是封装、继承和多态,其中在学习继承时了解到了菱形继承问题,写一篇博客记录一下(#^.^#)。

        菱形继承的定义:

                两个子类继承同一个父类,而又有子类同时继承这两个子类。

                

        这样做会引发什么问题呢?让我们来看下面这段代码:

#include<iostream>  
using namespace std;  
class Base  
{  
protected:  
    int _base;  
public:  
    void fun()  
    {  
        cout << "Base::fun" << endl;  
    }  
};  
  
class A:public Base  
{  
protected:  
    int _a;  
};  
  
class B : public Base  
{  
protected:  
    int _b;  
};  
class D :public A, public B  
{  
private:  
    int _d;  
};  
int main()  
{  
    D d;  
    d.fun();//编译器报错:调用不明确  
    getchar();  
}  

        在D的对象中包含了两份Base,当我们想要调用从Base中继承的fun()时,就会出现调用不明确的错误,还会造成数据冗余。解决方法如下:

        1.域限定:

        

int main()  
{  
    D d;  
    d.A::fun();  
    d.B::fun();  
    getchar();  
}  

        2.虚继承:

     

        这里的虚继承是指在D的父类A和B继承Base时加上virtual关键字,而不是D在继承AB时使用。

        此时A和B中不再保存Base中的内容,保存的是一份偏移地址,然后再将Base的数据保存在同一个地址中,此时我们再调用D中的fun()时就不会再报错了。

        虚继承和虚函数是完全不同的!这两个概念不要搞混。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
菱形继承指的是一个派生继承自两个直接或间接基,而这两个基又共同继承自一个共同的基,导致派生中存在两份共同基的数据成员,从而产生了命名冲突和二义性的问题。 解决菱形继承问题的一种方法是使用虚拟继承。虚拟继承可以使得共同基在派生中只有一份实例,从而避免了数据成员的重复和命名冲突问题。在使用虚拟继承时,需要在继承语句前加上关键字 virtual,例如: ``` class A { public: int a; }; class B : virtual public A { public: int b; }; class C : virtual public A { public: int c; }; class D : public B, public C { public: int d; }; ``` 在上面的例子中,B 和 C 都虚拟继承自 A,而 D 继承自 B 和 C。因此,在 D 中只有一份 A 的实例,从而避免了数据成员的重复和命名冲突问题。 在初始化菱形继承的派生时,需要注意以下几点: 1. 派生的构造函数必须调用每个直接基的构造函数,以及虚拟基的构造函数,顺序为先虚拟基,再按照继承的顺序调用直接基的构造函数。 2. 虚拟基的构造函数由最底层的派生负责调用,其他派生不需要再次调用虚拟基的构造函数。 3. 派生的析构函数必须调用每个直接基的析构函数,以及虚拟基的析构函数,顺序为先按照继承的顺序调用直接基的析构函数,再调用虚拟基的析构函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值