从C ++中具有多个继承的类派生的类:派生类正在尝试调用根基类构造函数

问题描述

很抱歉,这感觉像是my last question.的廉价续集

我有一个钻石继承人,其中D既来自BC,又来自A(实际上)。 ABC是抽象的,由于我以前的问题的回答,编译器现在已经意识到了,一切都很好。

现在,我需要创建一个E派生的类D。据我所知,通常构造函数E::E应该调用D::D,并且调用D::DA::A,和B::B

但是我的编译器确实坚持要C::C本身调用E::E

这是我做的一个简单示例:

A::A

这是编译错误

class A {                       //abstract
    protected:
        A(int foo) {}
        virtual void f() =0;
};

class B: public virtual A {     // abstract
    protected:
        B() {}
};

class C: public virtual A {     // abstract
    protected:
        C() {}
};

class D: public B,public C {   // concrete
    public:
        D(int foo,int bar) :A(foo) {}
        void f() {}
};

class E: public D {             // concrete
    public:
        E(int foo,int bar,int buz) :D(foo,bar) {}
};


int main()
{
    return 0;
}

我知道虚拟继承是正确的,并且我知道编译器知道我打算抽象哪些类以及可以实例化哪些类,因为如果删除$ g++ test.cpp test.cpp: In constructor ‘E::E(int,int,int)’: test.cpp:25:49: error: no matching function for call to ‘A::A()’ 25 | E(int foo,bar) {} | ^ test.cpp:3:9: note: candidate: ‘A::A(int)’ 3 | A(int foo) {} | ^ test.cpp:3:9: note: candidate expects 1 argument,0 provided test.cpp:1:7: note: candidate: ‘constexpr A::A(const A&)’ 1 | class A { //abstract | ^ test.cpp:1:7: note: candidate expects 1 argument,0 provided test.cpp:1:7: note: candidate: ‘constexpr A::A(A&&)’ test.cpp:1:7: note: candidate expects 1 argument,0 provided 代码就会编译。

我想念什么?

解决方法

但是我的编译器确实坚持要求E :: E本身调用A :: A。

就像我在回答上一个问题时所解释的那样:“派生最多的类的构造函数调用虚拟基础的构造函数”

包含虚拟基的层次结构中的所有非抽象类必须正确初始化虚拟基,因为它们可能会被实例化为派生程度最高的类。例如,如果您创建E的实例,那么E的构造函数将初始化虚拟基础A

在您的代码中,E的构造函数尝试通过省略初始化程序来使用默认的A构造函数。但是A无法默认构造,因此程序格式错误。

我想念什么?

A的构造函数中虚拟基础E的初始化程序。

据我所知,无法将虚拟基础的构建委派给其他具体基础,例如D