[class.mi]

# 11 Classes [[class]](./#class)

## 11.7 Derived classes [[class.derived]](class.derived#class.mi)

### 11.7.2 Multiple base classes [class.mi]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3683)

A class can be derived from any number of base classes[.](#1.sentence-1)

[*Note [1](#note-1)*:

The use of more than one direct base class is often called multiple inheritance[.](#1.sentence-2)

â *end note*]

[*Example [1](#example-1)*: class A { /* ... */ };class B { /* ... */ };class C { /* ... */ };class D : public A, public B, public C { /* ... */ }; â *end example*]

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3697)

[*Note [2](#note-2)*:

The order of derivation is not significant except as specified by the
semantics of initialization by constructor ([[class.base.init]](class.base.init "11.9.3 Initializing bases and members")),
cleanup ([[class.dtor]](class.dtor "11.4.7 Destructors")), and storage
layout ([[class.mem]](class.mem "11.4 Class members"), [[class.access.spec]](class.access.spec "11.8.2 Access specifiers"))[.](#2.sentence-1)

â *end note*]

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3707)

A class shall not be specified as a direct base class of a derived class
more than once[.](#3.sentence-1)

[*Note [3](#note-3)*:

A class can be an indirect base class more than once and can be a direct
and an indirect base class[.](#3.sentence-2)

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[.](#3.sentence-3)

However, the static members, enumerations and types can be
unambiguously referred to[.](#3.sentence-4)

â *end note*]

[*Example [2](#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*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3734)

A base class specifier that does not contain the keywordvirtual specifies a [*non-virtual base class*](#def:base_class,non-virtual "11.7.2 Multiple base classes [class.mi]")[.](#4.sentence-1)

A base
class specifier that contains the keyword virtual specifies a[*virtual base class*](#def:base_class,virtual "11.7.2 Multiple base classes [class.mi]")[.](#4.sentence-2)

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]](intro.object "6.8.2 Object model")) shall contain a
corresponding distinct base class subobject of that type[.](#4.sentence-3)

For each
distinct base class that is specified virtual, the most derived object
shall contain a single base class subobject of that type[.](#4.sentence-4)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3746)

[*Note [4](#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[.](#5.sentence-1)

Given the class C defined above, an
object of class C will have two subobjects of class L as
shown in Figure [4](#fig:class.nonvirt)[.](#5.sentence-2)

![SVG Image](data:image/svg+xml;base64, )  
Figure [4](#fig:class.nonvirt) — Non-virtual base [[fig:class.nonvirt]](./fig:class.nonvirt)

In such lattices, explicit qualification can be used to specify which
subobject is meant[.](#5.sentence-3)

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]](class.member.lookup "6.5.2 Member name lookup"))[.](#5.sentence-5)

â *end note*]

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3772)

[*Note [5](#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 { /* ... */ };

![SVG Image](data:image/svg+xml;base64, )  
Figure [5](#fig:class.virt) — Virtual base [[fig:class.virt]](./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[.](#6.sentence-1)

Given the class C defined above, an object of class C will have one subobject of
class V, as shown in Figure [5](#fig:class.virt)[.](#6.sentence-2)

â *end note*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3795)

[*Note [6](#note-6)*:

A class can have both virtual and non-virtual base classes of a given
type[.](#7.sentence-1)

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[.](#7.sentence-2)

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](#fig:class.virtnonvirt)[.](#7.sentence-3)

![SVG Image](data:image/svg+xml;base64, )  
Figure [6](#fig:class.virtnonvirt) — Virtual and non-virtual base [[fig:class.virtnonvirt]](./fig:class.virtnonvirt)

â *end note*]
