query in virtual inheritance

i have came across some snippets of code
1
2
3
4
5
6
7
8
9
10
11
12
13
class ClassSealer {
private:
   friend class Sealed;
   ClassSealer() {}
};
class Sealed : private virtual ClassSealer
{ 
   // ...
};
class FailsToDerive : public Sealed
{
   // Cannot be instantiated
};


explanation said that FailsToDerive won't compile as it must call the ClassSealer constructor directly (virtual inheritance requirement).

Can any one explain why virtual keyword not allowing to compile and requirement of virtual inheritance.

The point of virtual inheritance is to avoid the "deadly diamond" problem when a class attempts to inherit a base class multiple times, as would be the case if B and C both inherited from A, then D inherited B and C -- D de facto inherits A twice. The intention is to have D only have one copy of the members of A and have both B and C use that single copy.

In order to enable this, B and C have to use virtual inheritance when inheriting A.

But the problem then becomes ... since both B and C inherit from A, both B and C have to construct their "copy" of A in their constructors. Since there is only one A, one of these constructors would undo the effects of the other -- it is akin to calling a constructor twice for the same object. That obviously doesn't make sense, and rather than enforce some arcane thing like "the last constructor wins", it was decided that neither B nor C would invoke A's constructor; rather D would have to explicitly call A's constructor, and the compiler would ignore B and C's calls to A's constructor.

In the above case, since A (ClassSealer) has a private constructor, only friends of A (ClassSealer) may call it. The only friend of A is Sealed, per line 3, so only C can construct A. But because of the virtual inheritance rule, D (FailsToDerive) _must_ call A's (ClassSealer) constructor (even though it is in fact inherited only once), but it cannot.
The point of virtual inheritance is to avoid the "deadly diamond" problem when a class attempts to inherit a base class multiple times, as would be the case if B and C both inherited from A, then D inherited B and C -- D de facto inherits A twice. The intention is to have D only have one copy of the members of A and have both B and C use that single copy.

In order to enable this, B and C have to use virtual inheritance when inheriting A.

But the problem then becomes ... since both B and C inherit from A, both B and C have to construct their "copy" of A in their constructors. Since there is only one A, one of these constructors would undo the effects of the other -- it is akin to calling a constructor twice for the same object. That obviously doesn't make sense, and rather than enforce some arcane thing like "the last constructor wins", it was decided that neither B nor C would invoke A's constructor; rather D would have to explicitly call A's constructor, and the compiler would ignore B and C's calls to A's constructor.

In the above case, since A (ClassSealer) has a private constructor, only friends of A (ClassSealer) may call it. The only friend of A is Sealed, per line 3, so only C can construct A. But because of the virtual inheritance rule, D (FailsToDerive) _must_ call A's (ClassSealer) constructor (even though it is in fact inherited only once), but it cannot.
virtual is not the problem. Line 4 is the problem. The constructor is private and hence can't be called. virtual inheritance is for multiple inheritance. That is no data hiding.
coder777: That isn't quite true. Without virtual inheritance, FailsToDerive's default constructor (the only constructor) would only call Sealed's default constructor which would call ClassSealer's default constructor. Sealed can call ClassSealer's constructor.
jsmith: can elaborate little bit about virtual inheritance rule . i.e rule is that the derived class should able to call the all base class constructors.
I don't understand what it is you want me to explain above my first response. Is there something in particular you are unclear about?

sorry jsmith for delay.

i want to know how Virtual keyword makes the differences. if remove the virtual keyword, Compiler is not validating the whether instance of ClassSealer is created or not . if so ,why it should not b happen in the virtual presence
Topic archived. No new replies allowed.