Virtual inheritance

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 B and C inherit from a class A, and a class D inherits from both B and C, then D will contain two copies of A's member variables: one via B, and one via C. These will be accessible independently, using scope resolution. Instead, if classes B and C inherit virtually from class A, then objects of class D will contain only one set of the member variables from class A. Consider the following class hierarchy.

Comment
enVirtual 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 B and C inherit from a class A, and a class D inherits from both B and C, then D will contain two copies of A's member variables: one via B, and one via C. These will be accessible independently, using scope resolution. Instead, if classes B and C inherit virtually from class A, then objects of class D will contain only one set of the member variables from class A. Consider the following class hierarchy.
Depiction
Diamond inheritance.svg
Has abstract
enVirtual 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 B and C inherit from a class A, and a class D inherits from both B and C, then D will contain two copies of A's member variables: one via B, and one via C. These will be accessible independently, using scope resolution. Instead, if classes B and C inherit virtually from class A, then objects of class D will contain only one set of the member variables from class A. 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 (D in the example above) the virtual base (A) acts as though it were the direct base class of D, not a class derived indirectly through a base (B or C). 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 virtual keyword. Consider the following class hierarchy. struct Animal { virtual ~Animal = default; virtual void Eat {}};struct Mammal: Animal { virtual void Breathe {}};struct WingedAnimal: Animal { virtual void Flap {}};// A bat is a winged mammalstruct Bat: Mammal, WingedAnimal {};Bat bat; 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 subobjects. So an attempt to directly bind a reference to the Animal subobject of a Bat object would fail, since the binding is inherently ambiguous: Bat b;Animal& a = b; // error: which Animal subobject should a Bat cast into, // a Mammal::Animal or a WingedAnimal::Animal? To disambiguate, one would have to explicitly convert bat to either base class subobject: Bat b;Animal& mammal = static_cast<Mammal&>(b); Animal& winged = static_cast<WingedAnimal&>(b); In order to call Eat, the same disambiguation, or explicit qualification is needed: static_cast<mammal&> (bat).Eat </mammal&> or static_cast<wingedanimal&> (bat).Eat </wingedanimal&> or alternatively bat.Mammal::Eat and bat.WingedAnimal::Eat. 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 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 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.
Hypernym
Technique
Is primary topic of
Virtual inheritance
Label
enVirtual inheritance
Link from a Wikipage to an external page
godbolt.org/z/3nrejWfEW
godbolt.org/z/WGfa9bYG7
Link from a Wikipage to another Wikipage
Base class
C++
Category:C++
Category:Class (computer programming)
Diamond problem
File:Diamond inheritance.svg
Inheritance (computer science)
Keyword (computer programming)
Multiple inheritance
Scope resolution operator
Subobject
Vtable
SameAs
Herencia virtual
m.065cly
Q1526910
Virtuális öröklődés
X8Uh
Виртуальное наследование
Віртуальне успадкування
仮想継承
虚继承
Subject
Category:C++
Category:Class (computer programming)
Thumbnail
Diamond inheritance.svg?width=300
WasDerivedFrom
Virtual inheritance?oldid=1115669439&ns=0
WikiPageInterLanguageLink
Çoklu kalıtım
Multipelt arv
WikiPageLength
12719
Wikipage page ID
1907963
Wikipage revision ID
1115669439
WikiPageUsesTemplate
Template:'
Template:C++ programming language
Template:For
Template:Reflist