This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

150
cppdraft/class/mi.md Normal file
View 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.3Initializing bases and members")),
cleanup ([[class.dtor]](class.dtor "11.4.7Destructors")), and storage
layout ([[class.mem]](class.mem "11.4Class members"), [[class.access.spec]](class.access.spec "11.8.2Access 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.2Multiple 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.2Multiple 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.2Object 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,PHN2ZyBoZWlnaHQ9IjE0MHB0IiB3aWR0aD0iMjI0cHQiIHZpZXdCb3g9IjAuMDAgMC4wMCAyMjQuMDAgMTQwLjAwIj4KPGcgY2xhc3M9ImdyYXBoIj4Kbm9udmlydAoKPGcgY2xhc3M9Im5vZGUiPgpMMQpMCjwvZz4KCjxnIGNsYXNzPSJub2RlIj4KTDIKTAo8L2c+Cgo8ZyBjbGFzcz0ibm9kZSI+CkEKQQo8L2c+Cgo8ZyBjbGFzcz0iZWRnZSI+CkEtJmd0O0wxCjxwYXRoIGQ9Ik0yNywtNzYuNDFDMjcsLTgzLjMgMjcsLTkyLjkgMjcsLTEwMS40MyIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIC8+CjwvZz4KCjxnIGNsYXNzPSJub2RlIj4KQgpCCjwvZz4KCjxnIGNsYXNzPSJlZGdlIj4KQi0mZ3Q7TDIKPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTE4OSwtNzYuNDFDMTg5LC04My4zIDE4OSwtOTIuOSAxODksLTEwMS40MyIgLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIC8+CjwvZz4KCjxnIGNsYXNzPSJub2RlIj4KQwpDCjwvZz4KCjxnIGNsYXNzPSJlZGdlIj4KQy0mZ3Q7QQo8cGF0aCBzdHJva2U9ImJsYWNrIiBkPSJNOTQuMjYsLTIwLjE2QzgxLjg1LC0yOC40MyA2My4zNywtNDAuNzUgNDguOTIsLTUwLjM4IiBmaWxsPSJub25lIiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpDLSZndDtCCjxwYXRoIGQ9Ik0xMjEuNzQsLTIwLjE2QzEzNC4xNSwtMjguNDMgMTUyLjYzLC00MC43NSAxNjcuMDgsLTUwLjM4IiBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgo8L2c+Cjwvc3ZnPg==)
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.2Member 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,PHN2ZyB3aWR0aD0iMjI0cHQiIHZpZXdCb3g9IjAuMDAgMC4wMCAyMjQuMDAgMTQwLjAwIiBoZWlnaHQ9IjE0MHB0Ij4KPGcgY2xhc3M9ImdyYXBoIj4KdmlydAoKPGcgY2xhc3M9Im5vZGUiPgpWClYKPC9nPgoKPGcgY2xhc3M9Im5vZGUiPgpBCkEKPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpBLSZndDtWCjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik00MC43NCwtNzYuMTZDNTMuMTUsLTg0LjQzIDcxLjYzLC05Ni43NSA4Ni4wOCwtMTA2LjM4IiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgoKPGcgY2xhc3M9Im5vZGUiPgpCCkIKPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpCLSZndDtWCjxwYXRoIGQ9Ik0xNzUuMjYsLTc2LjE2QzE2Mi44NSwtODQuNDMgMTQ0LjM3LC05Ni43NSAxMjkuOTIsLTEwNi4zOCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIC8+CjwvZz4KCjxnIGNsYXNzPSJub2RlIj4KQwpDCjwvZz4KCjxnIGNsYXNzPSJlZGdlIj4KQy0mZ3Q7QQo8cGF0aCBzdHJva2U9ImJsYWNrIiBkPSJNOTQuMjYsLTIwLjE2QzgxLjg1LC0yOC40MyA2My4zNywtNDAuNzUgNDguOTIsLTUwLjM4IiBmaWxsPSJub25lIiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpDLSZndDtCCjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0xMjEuNzQsLTIwLjE2QzEzNC4xNSwtMjguNDMgMTUyLjYzLC00MC43NSAxNjcuMDgsLTUwLjM4IiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgo8L2c+Cjwvc3ZnPg==)
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,PHN2ZyBoZWlnaHQ9IjE0MHB0IiB2aWV3Qm94PSIwLjAwIDAuMDAgMzg2LjAwIDE0MC4wMCIgd2lkdGg9IjM4NnB0Ij4KPGcgY2xhc3M9ImdyYXBoIj4KdmlydG5vbnZpcnQKCjxnIGNsYXNzPSJub2RlIj4KQjEKQgo8L2c+Cgo8ZyBjbGFzcz0ibm9kZSI+CkIyCkIKPC9nPgoKPGcgY2xhc3M9Im5vZGUiPgpBQQpBQQo8L2c+Cgo8ZyBjbGFzcz0ibm9kZSI+ClgKWAo8L2c+Cgo8ZyBjbGFzcz0iZWRnZSI+CkFBLSZndDtYCjxwYXRoIGQ9Ik05NC4yNiwtMjAuMTZDODEuODUsLTI4LjQzIDYzLjM3LC00MC43NSA0OC45MiwtNTAuMzgiIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIC8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiAvPgo8L2c+Cgo8ZyBjbGFzcz0ibm9kZSI+ClkKWQo8L2c+Cgo8ZyBjbGFzcz0iZWRnZSI+CkFBLSZndDtZCjxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0xMjEuNzQsLTIwLjE2QzEzNC4xNSwtMjguNDMgMTUyLjYzLC00MC43NSAxNjcuMDgsLTUwLjM4IiBzdHJva2U9ImJsYWNrIiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgoKPGcgY2xhc3M9Im5vZGUiPgpaCloKPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpBQS0mZ3Q7Wgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBkPSJNMTM1LjQsLTE3LjA5QzE3OS4wOSwtMjYuOCAyNjQuNiwtNDUuOCAzMTMuNzgsLTU2LjczIiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpYLSZndDtCMQo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBkPSJNNDAuNzQsLTc2LjE2QzUzLjE1LC04NC40MyA3MS42MywtOTYuNzUgODYuMDgsLTEwNi4zOCIgLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIC8+CjwvZz4KCjxnIGNsYXNzPSJlZGdlIj4KWS0mZ3Q7QjEKPHBhdGggc3Ryb2tlPSJibGFjayIgZD0iTTE3NS4yNiwtNzYuMTZDMTYyLjg1LC04NC40MyAxNDQuMzcsLTk2Ljc1IDEyOS45MiwtMTA2LjM4IiBmaWxsPSJub25lIiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpaLSZndDtCMgo8cGF0aCBzdHJva2U9ImJsYWNrIiBkPSJNMzUxLC03Ni40MUMzNTEsLTgzLjMgMzUxLC05Mi45IDM1MSwtMTAxLjQzIiBmaWxsPSJub25lIiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgo8L2c+Cjwvc3ZnPg==)
Figure [6](#fig:class.virtnonvirt) — Virtual and non-virtual base [[fig:class.virtnonvirt]](./fig:class.virtnonvirt)
— *end note*]