创建从虚类继承的类

creation of a class that inherits from a virtual class

本文关键字:继承 创建      更新时间:2023-10-16

我想我理解了虚拟类的核心原理。但是我真的很困惑,当创建从虚类继承的对象时,到底发生了什么。

例如

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

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

这取决于BC是由自身构成还是作为D的子对象。当它们被构造为D对象的子对象时,你所说的是正确的。这是真的,因为D的构造函数在初始化列表中没有显式调用A的任何构造函数。

既然你使用了:

B(int n):A(10) {}  B():A(10) {} 
当您使用 构造B

B b;

A()没有被使用,但是A(10)被用来构造A子对象。

我猜,例如,当创建CA部分时,A的构造函数不会被再次调用,因为它已经创建了。我说的对吗?

您可以查看isocpp.org,特别是:"再一次:在多重继承和/或虚拟继承情况下,构造函数的确切顺序是什么?",其中声明:

首先要执行的构造函数是层次结构中任意位置的虚基类。它们按照它们在基类图的深度优先的从左到右遍历中出现的顺序执行,其中从左到右指的是基类名出现的顺序。

所有虚基类构造函数完成后,构造顺序一般是从基类到派生类。如果您想象编译器在派生类的actor中做的第一件事是对其非虚拟基类的actor进行隐藏调用,那么细节就很容易理解了(提示:许多编译器实际上就是这样做的)。因此,如果类D从B1和B2继承了乘法,则B1的构造函数先执行,然后是B2的构造函数,然后是D的构造函数。例如,如果B1继承了B1a和B1b, B2继承了B2a和B2b,那么最终的顺序是B1a、B1b、B1、B2a、B2b、B2、d。

请注意,B1和B2(或B1a和B1b)的顺序是由基类在类声明中出现的顺序决定的,而不是由初始化器在派生类的初始化列表中出现的顺序决定的。