无法从具有虚拟继承的 class 派生(C++ 虚拟继承)

Cannot derive from class with virtual inheritance (C++ virtual inheritance)

class Base
{
public:
    Base(std::string arg1, std::string arg2) : arg1(arg1), arg2(arg2) {}
    string arg1,arg2;
    virtual void f() = 0;
    inline virtual ~Base() {}
};

class Mixin1 : virtual public Base
{
};

//Virtual class uses virtual base and a mixin
class VirtualDerived : virtual public Base, public Mixin1
{
public:
    VirtualDerived(string arg2) : Base("some literal", arg2) {}
};

//Here I am concretely subclassing VirtualDerived, whose constructor constructs all virtual superclasses.
class ConcreteDerived : public VirtualDerived
{
public:
    ConcreteDerived(string arg2) : VirtualDerived(arg2) {}
    inline void f() {}
};

int main(int argc, const char * argv[]) {

    ConcreteDerived cd("hello");

    return 0;
}

我从 VirtualDerived 派生,其构造函数将初始化 Base。我是否显式声明 VirtualDerived 对 Mixin1 virtual 的继承与否没有区别。

我得到的错误是 ConcreteDerived 必须显式调用 Base 的构造函数。

使 ConcreteDerived 的继承虚拟化同样没有区别。

问题不在于 VirutalDerived 的构造函数转发。如果我实现 f 使其成为一个具体的 class,我可以毫无问题地创建它:

class VirtualDerived : virtual public Base, public Mixin1
{
public:
    VirtualDerived(string arg2) : Base("some literal", arg2) {}
    inline void f(){}
};

int main(int argc, const char * argv[]) {

    VirtualDerived cd("hello");

    return 0;
}

编译器似乎理解了直接创建VirtualDerived时VirtualDerived的构造函数调用了Base的非平凡构造函数。但如果某些东西派生 VirtualDerived 并调用它,则不会。为什么会这样?

关于虚继承要理解的一点是,当你从一个class虚继承时,它会转到继承"queue"的"front";也就是说,您必须在所有其他基础 classes.

之前初始化虚拟基础

在这种情况下,ConcreteDerived 通过 VirtualDerivedBase 作为间接虚拟基础。由于 Base 没有默认构造函数,您必须在 ConcreteDerived.

的初始化列表中指定它

推理是这样的:假设你有另一个中间体 class 例如

class VirtualDerived2 : virtual public Base
{
public:
    VirtualDerived2() : Base("arg1", "arg2") {}    
};

这里VirtualDerived2实际上也继承自Base,并用自己的一组参数初始化它。现在我们添加另一个具体的 class:

class ConcreteDerived2 : public VirtualDerived, public VirtualDerived2
{
    // ...
};

现在 ConcreteDerived2 有两个基础 class,它们实际上都继承自 Base。但是您在层次结构中只有 Base 的一个副本——这就是虚拟继承的全部要点。那么现在您要使用哪些参数来初始化 Base 的(单个)副本?来自 VirtualDerived 的那些,还是来自 VirtualDerived2 的那些?这个没有好的答案,所以C++让你选择最派生的class.