Virtual inheritance
Encyclopedia
Virtual inheritance is a topic of object-oriented programming
. It is a kind of inheritance
in which the part of the object that belongs to the virtual base class becomes common direct base for the derived class and any next class that derives from it. In other words, if class A is virtually derived from class V, and class B is derived (directly or indirectly) from A, then V becomes a direct base class of class B and any other class derived from A. The best known language which implements this feature is C++
.
This feature is most useful for multiple inheritance
, as it causes that subobject of the virtual base will be always a common subobject for all classes that are derived in the deriving class (as well as this class itself). This can be used to avoid the problem of ambiguous hierarchy composition (known as the "diamond problem
") by clarifying ambiguity over which ancestor class to use, as from the perspective of the deriving class (B in the example above) the virtual base (V) looks as if it was its direct base class, not a class being derived indirectly through its bases (A).
It is used when inheritance is representing restrictions of a set rather than composition of parts. In C++, a base class to be common in the hierarchy is denoted as virtual with the
.
As declared above, a call to
To disambiguate, one would have to explicitly convert either
In order to call
In this case, the double inheritance of
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
This is implemented by providing
Object-oriented programming
Object-oriented programming is a programming paradigm using "objects" – data structures consisting of data fields and methods together with their interactions – to design applications and computer programs. Programming techniques may include features such as data abstraction,...
. It is a kind of inheritance
Inheritance (computer science)
In object-oriented programming , inheritance is a way to reuse code of existing objects, establish a subtype from an existing object, or both, depending upon programming language support...
in which the part of the object that belongs to the virtual base class becomes common direct base for the derived class and any next class that derives from it. In other words, if class A is virtually derived from class V, and class B is derived (directly or indirectly) from A, then V becomes a direct base class of class B and any other class derived from A. The best known language which implements this feature is C++
C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
.
This feature is most useful for multiple inheritance
Multiple inheritance
Multiple inheritance is a feature of some object-oriented computer programming languages in which a class can inherit behaviors and features from more than one superclass....
, as it causes that subobject of the virtual base will be always a common subobject for all classes that are derived in the deriving class (as well as this class itself). This can be used to avoid the problem of ambiguous hierarchy composition (known as the "diamond problem
Diamond problem
In object-oriented programming languages with multiple inheritance and knowledge organization, the diamond problem is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C...
") by clarifying ambiguity over which ancestor class to use, as from the perspective of the deriving class (B in the example above) the virtual base (V) looks as if it was its direct base class, not a class being derived indirectly through its bases (A).
It is used when inheritance is representing restrictions of a set rather than composition of parts. In C++, a base class to be common in the hierarchy is denoted as virtual with the
virtual
keywordKeyword (computer programming)
In computer programming, a keyword is a word or identifier that has a particular meaning to the programming language. The meaning of keywords — and, indeed, the meaning of the notion of keyword — differs widely from language to language....
.
The problem
Consider the following class hierarchy.As declared above, a call to
bat.eat
is ambiguous because there are two Animal
(indirect) base classes in Bat
, so any Bat
object has two different Animal
base class sub-objects. So an attempt to directly bind a reference to the Animal
sub-object of a Bat
object would fail, since the binding is inherently ambiguous:To disambiguate, one would have to explicitly convert either
bat
to either base class sub-object:In order to call
eat
, the same disambiguation is needed: static_cast(bat).eat
or static_cast(bat).eat
.In this case, the double inheritance of
Animal
is probably unwanted, as we want to model that the relation (Bat
is an Animal
) exists only once; that a Bat
is a Mammal
and is a WingedAnimal
does not imply that it is an Animal
twice: an Animal
base class corresponds to a contract that Bat
implements (the "is a" relationship above really means "implements the requirements of"), and a Bat
only implements the Animal
contract once. The real world meaning of "is a only once" is that Bat
should have only one way of implementing eat
, not two different ways, depending on whether the Mammal
view of the Bat
is eating, or the WingedAnimal
view of the Bat
. (In the first code example we see that eat
is not overridden in either Mammal
or WingedAnimal
, so the two Animal
sub-objects will actually behave the same, but this is just a degenerate case, and that does not make a different from the C++ point of view.)This situation is sometimes referred to as diamond inheritance (see Diamond problem
Diamond problem
In object-oriented programming languages with multiple inheritance and knowledge organization, the diamond problem is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C...
) 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
Animal
portion of Bat::WingedAnimal
is now the same Animal
instance as the one used by Bat::Mammal
, which is to say that a Bat
has only one, shared, Animal
instance in its representation and so a call to Bat::eat
is unambiguous. Additionally, a direct cast from Bat
to Animal
is also unambiguous, now that there exists only one Animal
instance which Bat
could be converted to.This is implemented by providing
Mammal
and WingedAnimal
with a vtable pointer (or "vpointer") since the memory offset between the beginning of a Mammal
and of its Animal
part is unknown until runtime. Thus Bat becomes (vpointer
, Mammal
, vpointer
, WingedAnimal
, Bat
, Animal
). There are two vtable pointers, one per inheritance hierarchy that virtually inherits Animal
. In this example, one for Mammal
and one for WingedAnimal
. The object size has therefore increased by two pointers, but now there is only one Animal
and no ambiguity. All objects of type Bat
will have the same vpointers, but each Bat
object will contain its own unique Animal
object. If another class inherits from Mammal
, such as Squirrel
, then the vpointer in the Mammal
object in a Squirrel
will be different from the vpointer in the Mammal
object in a Bat
, although they can still be essentially the same in the special case that the Squirrel
part of the object has the same size as the Bat
part, because then the distance from the Mammal
to the Animal
part is the same. The vtables are not really the same, but all essential information in them (the distance) is.