给出以下代码(没有虚拟继承):
class A
{
public:
virtual void f() = 0;
};
class B : public A
{
public:
virtual void f() {}
};
class C : public A
{
public:
virtual void f() {}
};
class D : public B, public C
{
/* some code */
};
int main()
{
D d;
return 0;
}
代码编译。
另一方面,这里:
class A
{
public:
virtual void f() = 0;
};
class B : virtual public A
{
virtual void f() {}
};
class C : virtual public A
{
virtual void f() {}
};
class D : public B, public C
{
/* some code */
};
int main()
{
D d;
return 0;
}
编译器出现编译错误:
no unique final overrider for 'virtual void A::f()' in 'D' .
为什么第二个代码有所不同?
答案 0 :(得分:9)
您的第一个场景层次结构对应于:
F() F()
A A
| |
F() B C F()
\ /
D
其中D不是抽象的,因为在D类型的对象中有两个A子对象:一个由B通过B的格子具体化,另一个通过C的格子具体化。
除非你试图在D的对象上调用函数F(),否则不会有任何歧义。
您的第二个方案层次结构对应于:
F()
A
/ \
F() B C F()
\ /
D
在这种情况下,对象D有一个基类A子对象,它必须覆盖并提供该子对象中纯虚函数的实现。
Herb Sutter在本周大师(GOTW)中的文章是多重继承的好读物:
答案 1 :(得分:7)
使用虚拟继承,D
对象具有单个基类A
子对象。该单个子对象不能具有虚拟功能的两种不同实现。相比之下,如果没有虚拟继承,D
对象有两个不同的基类A
子对象,每个子对象都有自己的函数实现(直到你尝试在{{{ 1}}对象,此时你需要指出你想要的那个。)
干杯&第h