C++支持多重继承,有可能出现继承列表里的类有同一个父类的情况,比如下面这样:
A是base class,B、C、D都继承A。
逻辑上关系可以看成上面那样,但实际在内存布局中(memory layout),却是:
这样对子类D来说,就包含了两份A的数据成员。
这就出现了问题,在D中引用A的数据成员时,引用的是哪一个呢?
这种菱形继承来说,本来就是应该避免的,出现了也就意味着你的类设计上有了问题。
不过为了解决这个问题,C++引入了一个虚继承的机制,就是在继承一个类时,在public前或后加上virtual关键字,表明此父类对象只有一份拷贝。
我们就说这个被虚继承的类叫做virtual base class。如果不使用虚继承,当编译的时候就会报错了,可以自己修改试一下。
举例如下:
#include <iostream>
using namespace std;
class A {
public:
int a;
A(){
a = 10;
}
};
class B : public virtual A {
};
class C : virtual public A {
};
class D : public B, public C {
};
int main(){
//creating class D object
D object;
cout << "a = " << object.a << endl;
return 0;
}
当然,天下没有免费的午餐,使用virtual inheritance,自然要承担代价。
这个成本就是调用方式的改变,增加了操作降低了性能。
实现原理可以看这篇文章:
一言难尽,简单说就是将偏移地址存储在vtable中,这样想调用公共父类的成员时可以计算出地址。
参考: