简体   繁体   English

如何使用虚拟类实现此初始化列表?

[英]How is this initialization list implemented using a virtual class?

#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;
}

I am not being able to understand how the final output is zero. 我无法理解最终输出是如何为零。 Every time j is initialized in default way to some fixed value, how is the value initialized in the constructor of class D being passed to class A? 每次j以默认方式初始化为某个固定值时,如何将类D的构造函数中初始化的值传递给类A?

The rule with virtual base inheritance is: 具有虚拟基础继承的规则是:

"The most derived class in a hierarchy must construct a virtual base" “层次结构中派生程度最高的类必须构建虚拟基础”

In your case, from the most derived class D You explicitly called the constructor of A by passing an argument 0 So it sets the i to 0 . 在您的情况下,从最派生的类D您通过传递参数0显式调用A的构造函数,因此它将i设置为0 As mentioned in rule virtual base class is constructed through most derived class only and the other constructor calls through intermediate hierarchy have no effect since it is only constructed once. 如规则中所述,虚拟基类仅通过大多数派生类构造,而其他构造函数通过中间层次结构调用没有任何效果,因为它只构造一次。

The order of calling is: 通话顺序是:

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

Good Read: 好读:
Why virtual base class constructors called first? 为什么虚拟基类构造函数首先调用?

Since A is a virtual base class, it should be constructed only once, so it is not possible to create it with different constructor parameters, and the C++ compiler has to choose one way of creating a base class. 由于A是一个虚拟基类,因此它只应构造一次,因此不可能使用不同的构造函数参数创建它,并且C ++编译器必须选择一种创建基类的方法。

The obvious question is: which one is used? 显而易见的问题是:使用哪一个?

And the rule is: the one specified in the most derived class that inherits A directly. 规则是:在最派生类中指定的直接继承A的规则。

The initialization order is simple: first A (with the parameter value from D constructor initialization list), then B (it is D's first ancestor; and it uses the instance of A created before), then C (and it shares the same A instance), finally D (and it also shares the same A object as B and C). 初始化顺序很简单:首先是A(带有来自D构造函数初始化列表的参数值),然后是B(它是D的第一个祖先;它使用之前创建的A的实例),然后是C(并且它共享相同的A实例) ),最后是D(它也与B和C共享相同的A对象)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM