假设我有一个基类A,而B类派生自它。 B等级C等等..... Y来自Z。
当我实例化Z类时,谁将负责初始化A类的数据成员?
答案 0 :(得分:1)
从类继承时,在派生类之前调用基类的构造函数。您可以使用初始化列表控制传递给它的内容:
struct A
{
A();
A(int);
}
struct B
{
B(){} // A() is called implicitly.
B(int x) : A(x) {} // A(int) is called explicitly.
}
答案 1 :(得分:0)
沿着链派生的任何类都可以负责,以根据其可访问性初始化数据成员。
一种常见方法是为数据成员提供A类构造函数需求值。 B类会将这些变量添加到它的构造函数中,依此类推。
答案 2 :(得分:0)
它可以是A到Z中的任何一个类,它完全取决于您的情况。如果A类在其构造函数中使用param a b和c,那么B类必须提供这些,如果它在构造函数中依次要求传递b c,那么它将下降到C类以提供这些等等。子类可以选择提供一个尚未在构造函数中传递的值,因此后续的子代将不再需要提供此值。
答案 3 :(得分:0)
AFAIK,A的构造函数将负责A的数据成员的初始化,因为类是从上到下构建的,或者是Base-before-Derived。这就是为什么你不能在构造函数中使用纯虚拟成员函数的原因,因为尚未创建定义它的派生类。
答案 4 :(得分:0)
每个类的每个构造函数都构造所有直接的非虚拟基类。这可以递归地解释您的设置中发生的事情。
相比之下,虚拟基类是由派生程度最高的类的构造函数构建的。
这是一个明确提到基本构造函数的典型示例:
struct A { A(int, int) { /* ... */ ; };
struct B : A { B(char, bool) : A(2, 3) { /* ... */ };
struct C : B { C() : B('x', false) { /* ... */ };
C c; // calls A::A(2, 3), then B::B('x', false), then C::C()