[英]Class derived from a class with multiple inheritance in C++: the derived class is trying to call the root base class constructor
I'm sorry if this feels like a cheap sequel to my last question.如果这感觉像是我上一个问题的廉价续集,我很抱歉。
I have a diamond inheritance where D
is derived from both B
and C
, who in turn are both derived (virtually) from A
.我有一个钻石继承,其中
D
源自B
和C
,而后者又(实际上)源自A
。 A
, B
and C
are abstract, and thanks to the answers to my previous questions the compiler is now aware of it and all is fine. A
、 B
和C
是抽象的,多亏了我之前问题的答案,编译器现在知道了,一切都很好。
Now, I need to create a class E
derived from D
.现在,我需要创建一个从
D
派生的类E
。 As far as I know, normally the constructor E::E
should call D::D
, and it would be D::D
's job to call all of A::A
, B::B
, and C::C
.据我所知,通常构造函数
E::E
应该调用D::D
,而调用所有A::A
、 B::B
和C::C
是D::D
的工作.
But my compiler really insists on having E::E
call A::A
itself.但是我的编译器确实坚持让
E::E
调用A::A
本身。
Here is a simple example I made:这是我制作的一个简单示例:
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;
}
And here is the compilation error:这是编译错误:
$ 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
I know the virtual inheritance is correct and I know the compiler knows which classes I intend to be abstract and which I intend to be instantiable, because if I remove class E
, the code compiles.我知道虚拟继承是正确的,我知道编译器知道我打算抽象哪些类以及我打算实例化哪些类,因为如果我删除
class E
,代码会编译。
What am I missing?我错过了什么?
But my compiler really insists on having E::E call A::A itself.
但是我的编译器确实坚持让 E::E 调用 A::A 本身。
Like I explained in anwer to your previous question: "the constructor of the most derived class calls the constructor of the virtual base" .就像我在回答您之前的问题时所解释的那样: “最派生类的构造函数调用虚拟基类的构造函数” 。
All non-abstract classes in a hierarchy that contains virtual bases must correctly initialise the virtual bases because they can potentially be instantiated as the most derived class.包含虚拟基类的层次结构中的所有非抽象类都必须正确初始化虚拟基类,因为它们可能被实例化为最派生的类。 For example, if you create an instance of
E
, then it is the constructor of E
that initialises the virtual base A
.例如,如果您创建的实例
E
,那么它的构造函数E
是初始化虚拟基地A
。
In your code, the constructor of E
attempts to use the default constructor of A
by omitting the initialiser.在您的代码中,
E
的构造函数尝试通过省略初始化程序来使用A
的默认构造函数。 But A
is not default constructible, so the program is ill-formed.但是
A
不是默认可构造的,因此程序格式错误。
What am I missing?
我错过了什么?
The initialiser for the virtual base A
in the constructor of E
. E
的构造函数中虚基A
的初始化器。
As far as I know, there is no way to delegate the construction to of the virtual base to another concrete base such as D
.据我所知,无法将虚拟基础的构造委托给另一个具体基础,例如
D
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.