【发布时间】:2020-11-09 16:44:58
【问题描述】:
如果这感觉像是 my last question. 的廉价续集,我很抱歉
我有一个菱形继承,其中D 派生自B 和C,而这两者又都(实际上)派生自A。 A、B 和 C 是抽象的,多亏了我之前问题的答案,编译器现在知道了,一切都很好。
现在,我需要创建一个派生自 D 的类 E。据我所知,通常构造函数E::E 应该调用D::D,而调用所有A::A、B::B 和C::C 将是D::D 的工作。
但我的编译器确实坚持让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,代码就会编译。
我错过了什么?
【问题讨论】:
-
编译器告诉你 A 的哪些构造函数可用。您可以看到您定义的 A(int),加上复制和移动构造函数。通过定义自己的 A 构造函数,您可以告诉编译器不要声明默认构造函数。查看示例en.cppreference.com/w/cpp/language/default_constructor
标签: c++ multiple-inheritance instantiation