Why must virtual base classes be constructed by the most derived class?

强颜欢笑 提交于 2019-12-28 03:05:22

问题


The following code won't compile:

class A {
public:
    A(int) {}
};

class B: virtual public A {
public:
    B(): A(0) {}
};

// most derived class
class C: public B {
public:
    C() {} // wrong!!!
};

If I call A's constructor in C's constructor initialization list, that is:

// most derived class
class C: public B {
public:
    C(): A(0) {} // OK!!!
};

it does work.

Apparently, the reason is because virtual base classes must always be constructed by the most derived classes.

I don't understand the reason behind this limitation.


回答1:


Because it avoids this:

class A {
public:
    A(int) {}
};

class B0: virtual public A {
public:
    B0(): A(0) {}
};

class B1: virtual public A {
public:
    B1(): A(1) {}
};

class C: public B0, public B1 {
public:
    C() {} // How is A constructed? A(0) from B0 or A(1) from B1?
};



回答2:


Because in the class hierarchy having a virtually inherited base class, the base class would/may be shared by multiple classes (in diamond inheritance for example, where the same base class is inherited by multiple classes). It means, there would be only one copy of the virtually-inherited base class. It essentially means, the base class must be constructed first. It eventually means the derived class must instantiate the given base class.

For example:

class A;
class B1 : virtual A;
class B2 : virtual A;
class C: B1,B2 // A is shared, and would have one copy only.



回答3:


I find this rule error-prone and cumbersome (but then, what part of multiple inheritance isn't?).

But the logically imposed order of construction must differ from the case of normal (non-virtual) inheritance. Consider Ajay's example, minus virtual:

class A;
class B1 : A;
class B2 : A;
class C: B1,B2

In this case for each C two As are constructed, one as part of B1, the other one as part of B2. The code of the B classes is responsible for that, and can do it. The order of events is:

Start C ctor
   Start B1 ctor
      A ctor (in B's ctor code)
   End B1 ctor
   Start B2 ctor
      A ctor (in B's ctor code)
   End B2 ctor
End C ctor

Now consider virtual inheritance in

class A;
class B1 : virtual A;
class B2 : virtual A;
class C: B1,B2 

One order of event is

Start C ctor
   A ctor // not B's code!
   Start B1 ctor
      // NO A ctor
   End B1 ctor
   Start B2 ctor
      // NO A ctor
   End B2 ctor
End C ctor

The important logical distinction is that the virtually inherited base class sub-object of type A is part of the most derived class and under the control of it (here C).

B's constructors know nothing about and cannot access A. Consequently they cannot construct sub-objects of A, including base classes.



来源:https://stackoverflow.com/questions/44324583/why-must-virtual-base-classes-be-constructed-by-the-most-derived-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!