面向对象的三大基本特性是封装、继承和多态,其中在学习继承时了解到了菱形继承问题,写一篇博客记录一下(#^.^#)。
菱形继承的定义:
两个子类继承同一个父类,而又有子类同时继承这两个子类。
这样做会引发什么问题呢?让我们来看下面这段代码:
#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()时就不会再报错了。
虚继承和虚函数是完全不同的!这两个概念不要搞混。