Search code examples
c++inheritanceaccess-controlvirtual-inheritancesealed

Sealing classes in C++ and virtual inheritance


class ClassSealer {
private:
   friend class Sealed;
   ClassSealer() {}
};
class Sealed : public ClassSealer
{ 
   // ...
};
class FailsToDerive : public Sealed
{
   // This class is capable of being instantiated
};

The above fails to seal the class, but the following works, why?

class ClassSealer {
private:
   friend class Sealed;
   ClassSealer() {}
};
class Sealed : public virtual ClassSealer
{ 
   // ...
};
class FailsToDerive : public Sealed
{
   // Cannot be instantiated
};

What is happening here? What role does virtual inheritance does play here?


Solution

  • For normal inheritance, the derived class's constructor only calls the constructors of the direct base classes. So in the first example, the constructor of FailsToDerive calls the constructor of Sealed, which in turn calls the constructor of ClassSealer, which it is allowed to do.

    The constructor of a virtually inherited base, however, is called by the constructor of the most derived class. So in the second example, FailsToDerive's constructor needs to be able to call ClassSealer's constructor, which it is not allowed to do since it is not a friend of ClassSealer.