Init
This commit is contained in:
150
cppdraft/class/mi.md
Normal file
150
cppdraft/class/mi.md
Normal file
@@ -0,0 +1,150 @@
|
||||
[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)
|
||||
|
||||

|
||||
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 { /* ... */ };
|
||||
|
||||

|
||||
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)
|
||||
|
||||

|
||||
Figure [6](#fig:class.virtnonvirt) — Virtual and non-virtual base [[fig:class.virtnonvirt]](./fig:class.virtnonvirt)
|
||||
|
||||
â *end note*]
|
||||
Reference in New Issue
Block a user