10 KiB
[class.mi]
11 Classes [class]
11.7 Derived classes [class.derived]
11.7.2 Multiple base classes [class.mi]
A class can be derived from any number of base classes.
[Note 1:
The use of more than one direct base class is often called multiple inheritance.
â end note]
[Example 1: class A { /* ... / };class B { / ... / };class C { / ... / };class D : public A, public B, public C { / ... */ }; â end example]
[Note 2:
The order of derivation is not significant except as specified by the semantics of initialization by constructor ([class.base.init]), cleanup ([class.dtor]), and storage layout ([class.mem], [class.access.spec]).
â end note]
A class shall not be specified as a direct base class of a derived class more than once.
[Note 3:
A class can be an indirect base class more than once and can be a direct and an indirect base class.
There are limited things that can be done with such a class; lookup that finds its non-static data members and member functions in the scope of the derived class will be ambiguous.
However, the static members, enumerations and types can be unambiguously referred to.
â end note]
[Example 2: class X { /* ... / };class Y : public X, public X { / ... / }; // errorclass L { public: int next; / ... / };class A : public L { / ... / };class B : public L { / ... / };class C : public A, public B { void f(); / ... / }; // well-formedclass D : public A, public L { void f(); / ... */ }; // well-formed â end example]
A base class specifier that does not contain the keywordvirtual specifies a non-virtual base class.
A base class specifier that contains the keyword virtual specifies avirtual base class.
For each distinct occurrence of a non-virtual base class in the class lattice of the most derived class, the most derived object ([intro.object]) shall contain a corresponding distinct base class subobject of that type.
For each distinct base class that is specified virtual, the most derived object shall contain a single base class subobject of that type.
[Note 4:
For an object of class type C, each distinct occurrence of a (non-virtual) base class L in the class lattice of C corresponds one-to-one with a distinct L subobject within the object of type C.
Given the class C defined above, an object of class C will have two subobjects of class L as shown in Figure 4.
Figure 4 — Non-virtual base [fig:class.nonvirt]
In such lattices, explicit qualification can be used to specify which subobject is meant.
The body of function C::f can refer to the member next of each L subobject:void C::f() { A::next = B::next; } // well-formed
Without the A:: or B:: qualifiers, the definition ofC::f above would be ill-formed because of ambiguity ([class.member.lookup]).
â end note]
[Note 5:
In contrast, consider the case with a virtual base class:class V { /* ... / };class A : virtual public V { / ... / };class B : virtual public V { / ... / };class C : public A, public B { / ... */ };
Figure 5 — Virtual base [fig:class.virt]
For an object c of class type C, a single subobject of type V is shared by every base class subobject of c that has avirtual base class of type V.
Given the class C defined above, an object of class C will have one subobject of class V, as shown in Figure 5.
â end note]
[Note 6:
A class can have both virtual and non-virtual base classes of a given type.
class B { /* ... / };class X : virtual public B { / ... / };class Y : virtual public B { / ... / };class Z : public B { / ... / };class AA : public X, public Y, public Z { / ... */ };
For an object of class AA, all virtual occurrences of base class B in the class lattice of AA correspond to a single B subobject within the object of type AA, and every other occurrence of a (non-virtual) base class B in the class lattice of AA corresponds one-to-one with a distinctB subobject within the object of type AA.
Given the class AA defined above, class AA has two subobjects of class B: Z's B and the virtual B shared by X and Y, as shown in Figure 6.
Figure 6 — Virtual and non-virtual base [fig:class.virtnonvirt]
â end note]