3
#include<iostream.h>  
class A{  
  public:  
        int i;  
            A(int j=3):i(j){}  
};  
class B:virtual public A{  
  public:  
        B(int j=2):A(j){}  
};  
class C:virtual public A{  
  public:  
        C(int j=1):A(j){}  
};  
class D:public B, public C {    
  public:  
        D(int j=0):A(j), B(j+1), C(j+2){}  
};

int main()  
{  
    D d;   
    cout<<d.i;  
    return 0;
}

我无法理解最终输出如何为零。每次 j 以默认方式初始化为某个固定值时,如何将 D 类的构造函数中初始化的值传递给 A 类?

4

2 回答 2

2

虚拟基继承的规则是:

“层次结构中最派生的类必须构造一个虚拟基”

在您的情况下,从最派生的类您 通过传递参数D显式调用构造函数,因此它将设置为。如规则中所述,虚拟基类仅通过大多数派生类构造,而通过中间层次结构的其他构造函数调用无效,因为它只构造一次。A0i0

调用顺序为:

A(int)
B(int)
C(int)

好读:
为什么首先调用虚拟基类构造函数?

于 2013-01-06T07:44:51.047 回答
2

由于A是一个虚拟基类,它应该只被构造一次,所以不可能用不同的构造函数参数来创建它,C++编译器不得不选择一种创建基类的方式。

显而易见的问题是:使用哪一个?

规则是:在直接继承 A 的最派生类中指定的那个。

初始化顺序很简单:首先是 A(使用 D 构造函数初始化列表中的参数值),然后是 B(它是 D 的第一个祖先;它使用之前创建的 A 的实例),然后是 C(它共享同一个 A 实例),最后是 D(它还与 B 和 C 共享相同的 A 对象)。

于 2013-01-06T08:06:16.667 回答