创建一个继承自虚拟类

时间:2015-09-14 18:36:44

标签: c++ inheritance

我认为我理解虚拟类的核心原则。但我真的很困惑在创建从虚拟类继承的对象时会发生什么。

例如: (输出为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的构造函数不会再被调用,因为它已经创建了。我是对的吗?

2 个答案:

答案 0 :(得分:0)

  

但是当构建&#34; A部分&#34>时会发生什么? C和B的&#34;创建的A的单个实例&#34;。我知道,首先,隐式调用A的构造函数,因为有一个默认的构造函数),然后是所有直接的基类。

这取决于BC是由其自身构建还是作为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>