我认为我理解虚拟类的核心原则。但我真的很困惑在创建从虚拟类继承的对象时会发生什么。
例如: (输出为5)
#include <iostream>
using namespace std;
struct A {
public: int myInt;
A():myInt(5) {}
A(int n): myInt(n) {}
};
class B : virtual public A {
public:
B(int n):A(10) {} B():A(10) {}
};
class C : virtual public A {
public:
C(int n):A(3*n) {}
};
class D : public B, public C {
public:
D(int n=90) : C(2*n), B(n) {}
};
int main() {
D d(100);
cout << d.myInt << endl;
return 0;
}
我理解,首先,派生程度最高的类必须构造虚拟类。然后,基类,然后输入构造函数。
但是,根据“创建的A的单个实例”构造C和B的“A部分”时会发生什么。 我知道,首先,隐式调用A的构造函数,因为有一个默认构造函数),然后是所有直接基类。
我想在创建例如C的A部分时,A的构造函数不会再被调用,因为它已经创建了。我是对的吗?
答案 0 :(得分:0)
但是当构建&#34; A部分&#34>时会发生什么? C和B的&#34;创建的A的单个实例&#34;。我知道,首先,隐式调用A的构造函数,因为有一个默认的构造函数),然后是所有直接的基类。
这取决于B
或C
是由其自身构建还是作为D
的子对象构建。当它们被构造为D
对象的子对象时,你所说的是真的。这是正确的,因为D
的构造函数没有在初始化列表中显式调用任何A
的构造函数。
因为您使用:
B(int n):A(10) {} B():A(10) {}
使用
构建B
时
B b;
A()
未使用,但A(10)
用于构建A
子对象。
我想在创建时,例如
A
部分C
部分,A
的构造函数自已创建之后不会再次调用。我是对的吗?
是的,你是对的。
答案 1 :(得分:0)
您可以查看isocpp.org,特别是:&#34;再一次:多重和/或虚拟继承情况下构造函数的确切顺序是什么?&#34;,哪些状态:
要执行的第一个构造函数是层次结构中任何位置的虚拟基类。它们按照它们出现在基类图的深度优先从左到右遍历的顺序执行,其中从左到右指的是基类名称的出现顺序。
完成所有虚拟基类构造函数后,构造顺序通常从基类到派生类。如果您想象编译器在派生类的ctor中做的第一件事就是对其非虚基类的ctors进行隐藏调用(提示:这就是许多编译器实际执行的方式),这些细节最容易理解。 。因此,如果D类继承了B1和B2的乘法,则B1的构造函数首先执行,然后执行B2的构造函数,然后执行D的构造函数。此规则以递归方式应用;例如,如果B1继承自B1a和B1b,B2继承自B2a和B2b,则最终的顺序为B1a,B1b,B1,B2a,B2b,B2,D。
请注意,B1和B2(或B1a然后B1b)的顺序由基类出现在类的声明中的顺序决定,而不是初始化程序出现在派生类的初始化列表中的顺序。 / p>