Virtual inheritance

Virtual inheritance is a C++ technique that ensures only one copy of a base class's member variables are inherited by grandchild derived classes. Without virtual inheritance, if two classes  and   inherit from a class , and a class   inherits from both   and  , then   will contain two copies of  's member variables: one via  , and one via. These will be accessible independently, using scope resolution.

Instead, if classes  and   inherit virtually from class , then objects of class   will contain only one set of the member variables from class.

This feature is most useful for multiple inheritance, as it makes the virtual base a common subobject for the deriving class and all classes that are derived from it. This can be used to avoid the diamond problem by clarifying ambiguity over which ancestor class to use, as from the perspective of the deriving class ( in the example above) the virtual base  acts as though it were the direct base class of , not a class derived indirectly through a base (  or  ).

It is used when inheritance represents restriction of a set rather than composition of parts. In C++, a base class intended to be common throughout the hierarchy is denoted as virtual with the  keyword.

Consider the following class hierarchy.



As declared above, a call to  is ambiguous because there are two   (indirect) base classes in , so any   object has two different   base class subobjects. So, an attempt to directly bind a reference to the  subobject of a   object would fail, since the binding is inherently ambiguous:

To disambiguate, one would have to explicitly convert  to either base class subobject:

In order to call, the same disambiguation, or explicit qualification is needed:   or   or alternatively   and. Explicit qualification not only uses an easier, uniform syntax for both pointers and objects but also allows for static dispatch, so it would arguably be the preferable method.

In this case, the double inheritance of  is probably unwanted, as we want to model that the relation (  is an  ) exists only once; that a   is a   and is a , does not imply that it is an   twice: an   base class corresponds to a contract that   implements (the "is a" relationship above really means "implements the requirements of"), and a   only implements the   contract once. The real world meaning of "is a only once" is that  should have only one way of implementing , not two different ways, depending on whether the   view of the   is eating, or the   view of the. (In the first code example we see that  is not overridden in either   or , so the two   subobjects will actually behave the same, but this is just a degenerate case, and that does not make a difference from the C++ point of view.)

This situation is sometimes referred to as diamond inheritance (see Diamond problem) because the inheritance diagram is in the shape of a diamond. Virtual inheritance can help to solve this problem.

The solution
We can re-declare our classes as follows: The  portion of   is now the same   instance as the one used by , which is to say that a   has only one, shared,   instance in its representation and so a call to   is unambiguous. Additionally, a direct cast from  to   is also unambiguous, now that there exists only one   instance which   could be converted to.

The ability to share a single instance of the  parent between   and   is enabled by recording the memory offset between the   or   members and those of the base   within the derived class. However this offset can in the general case only be known at runtime, thus  must become. There are two vtable pointers, one per inheritance hierarchy that virtually inherits. In this example, one for  and one for. The object size has therefore increased by two pointers, but now there is only one  and no ambiguity. All objects of type  will use the same vpointers, but each   object will contain its own unique   object. If another class inherits from, such as  , then the vpointer in the   part of   will generally be different to the vpointer in the   part of   though they may happen to be the same if the   class be the same size as.

Additional Example of Several Ancestors
This example to illustrates a case where base class  has a constructor variable   and an additional ancestor   is derived from grandchild class. A  / \ B  C   \ / D  | E Here,  must be constructed in both   and. Further, inspection of the variable  illustrates how class   becomes a direct base class of its deriving class, as opposed to a base class of any intermediate deriving classed between   and the final deriving class. The code below may be explored interactively here.

Pure Virtual Methods
Suppose a pure virtual method is defined in the base class. If a deriving class inherits the base class virtually, then the pure virtual method does not need to be defined in that deriving class. However, if the deriving class does not inherit the base class virtually, then all virtual methods must be defined. The code below may be explored interactively here.