query in virtual inheritance

Feb 21, 2011 at 7:58pm
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.

Feb 21, 2011 at 8:30pm
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.
Feb 21, 2011 at 8:30pm
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.
Feb 21, 2011 at 8:33pm
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.
Feb 21, 2011 at 8:42pm
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.
Feb 22, 2011 at 7:32pm
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.
Feb 22, 2011 at 7:59pm
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?

Feb 25, 2011 at 7:55pm
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.