首页 > 解决方案 > 从 C++ 中具有多重继承的类派生的类:派生类正在尝试调用根基类构造函数

问题描述

如果这感觉像是我上一个问题的廉价续集,我很抱歉

我有一个钻石继承,其中D来自BC,而后者又都来自(实际上)来自AAB并且C是抽象的,并且由于对我以前的问题的回答,编译器现在已经意识到它并且一切都很好。

现在,我需要创建一个ED. 据我所知,通常构造函数E::E应该调用D::DD::D调用所有A::A,B::BC::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, int bar, int buz) :D(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

我知道虚拟继承是正确的,并且我知道编译器知道哪些类是抽象的,哪些是可实例化的,因为如果我删除class E,代码就会编译。

我错过了什么?

标签: c++multiple-inheritanceinstantiation

解决方案


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

就像我在回答您之前的问题时所解释的那样:“最派生类的构造函数调用虚拟基的构造函数”

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

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

我错过了什么?

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

据我所知,没有办法将虚拟基础的构建委托给另一个具体基础,例如D.


推荐阅读