C++中的虚继承是什么?

9
假设我有这段代码:
class A {
};
class B: virtual public A {
};
class C: virtual public A {
};

class D: public B,public C, virtual public A {
};

如果 D 继承了 BC,虚拟继承可以确保 D 中只有一个 A 的副本;但是如果 D 再次使用 virtual public A 继承 A,像上面的代码一样,会发生什么呢?
会有一个类型为 A 的子对象,还是两个?
我仍然对一些虚拟继承的表达式感到困惑,例如:
#include <iostream>
using namespace std;

class A {
    public:
    A() {std::cout<<"A ";}
};

class B: A {
    public:
    B() {std::cout<<"B ";}
};

class AToo: virtual A {
    public:
    AToo() {
    std::cout<<"AToo ";
}
};

class ATooB: virtual AToo, virtual B {
    public: 
    ATooB() {
    std::cout<<"ATooB ";
}
};
< p >虚拟关键字是否能够确保< code > A < / code >在< code > ATooB < / code >中只有一个副本?如果< code > AToo < / code >使用虚拟继承从< code > A < / code >继承,但是< code > B < / code >没有,那么会发生什么?< code > ATooB < / code >中会有两个副本吗?这是否意味着< code > B < / code >和< code > AToo < / code >都应该对< code > A < / code >使用虚拟继承以确保< code > ATooB < / code >只有一个副本?< / p>

根据您的编辑,我修改了我的回答。 - Alexander Gessler
这个回答解决了你的问题吗?在C++中,什么是虚基类? - Karl Knechtel
2个回答

11

这是virtual继承的预期使用方式之一,A只有一个副本。

您实际上可以轻易地验证它。给A添加一个成员,并使用D实例对其进行修改。如果存在多个A的副本,则编译器会报告访问不明确。

编辑在编辑后的问题中,将存在两个A的副本。每次常规继承A(没有virtual)时,都会创建一个新的A副本。如果您想要一个副本,请每次声明为virtual


4

从标准文档 10.1.4 中可以得知:

对于每个被指定为虚拟的不同基类,最终派生的对象将只包含一个该类型的基类子对象。...

因此,确实只有一个。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接