tmp/tmppqgmk8gw/{from.md → to.md}
RENAMED
|
@@ -1,56 +1,72 @@
|
|
| 1 |
## Multiple base classes <a id="class.mi">[[class.mi]]</a>
|
| 2 |
|
| 3 |
-
A class can be derived from any number of base classes.
|
| 4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
|
| 6 |
``` cpp
|
| 7 |
-
class A {
|
| 8 |
-
class B {
|
| 9 |
-
class C {
|
| 10 |
-
class D : public A, public B, public C {
|
| 11 |
```
|
| 12 |
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
|
|
|
|
|
|
| 17 |
|
| 18 |
A class shall not be specified as a direct base class of a derived class
|
| 19 |
-
more than once.
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
|
| 26 |
``` cpp
|
| 27 |
-
class X {
|
| 28 |
-
class Y : public X, public X {
|
| 29 |
```
|
| 30 |
|
| 31 |
``` cpp
|
| 32 |
-
class L { public: int next;
|
| 33 |
-
class A : public L {
|
| 34 |
-
class B : public L {
|
| 35 |
-
class C : public A, public B { void f();
|
| 36 |
-
class D : public A, public L { void f();
|
| 37 |
```
|
| 38 |
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
|
|
|
|
|
|
| 42 |
each distinct occurrence of a non-virtual base class in the class
|
| 43 |
lattice of the most derived class, the most derived object (
|
| 44 |
[[intro.object]]) shall contain a corresponding distinct base class
|
| 45 |
subobject of that type. For each distinct base class that is specified
|
| 46 |
virtual, the most derived object shall contain a single base class
|
| 47 |
-
subobject of that type.
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
|
| 53 |
<a id="fig:nonvirt"></a>
|
| 54 |
|
| 55 |
![Non-virtual base \[fig:nonvirt\]](images/fignonvirt.svg)
|
| 56 |
|
|
@@ -63,46 +79,58 @@ void C::f() { A::next = B::next; } // well-formed
|
|
| 63 |
```
|
| 64 |
|
| 65 |
Without the `A::` or `B::` qualifiers, the definition of `C::f` above
|
| 66 |
would be ill-formed because of ambiguity ([[class.member.lookup]]).
|
| 67 |
|
| 68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
|
| 70 |
``` cpp
|
| 71 |
-
class V {
|
| 72 |
-
class A : virtual public V {
|
| 73 |
-
class B : virtual public V {
|
| 74 |
-
class C : public A, public B {
|
| 75 |
```
|
| 76 |
|
| 77 |
-
for an object `c` of class type `C`, a single subobject of type `V` is
|
| 78 |
-
shared by every base subobject of `c` that has a `virtual` base class of
|
| 79 |
-
type `V`. Given the class `C` defined above, an object of class `C` will
|
| 80 |
-
have one subobject of class `V`, as shown below.
|
| 81 |
-
|
| 82 |
<a id="fig:virt"></a>
|
| 83 |
|
| 84 |
![Virtual base \[fig:virt\]](images/figvirt.svg)
|
| 85 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
A class can have both virtual and non-virtual base classes of a given
|
| 87 |
type.
|
| 88 |
|
| 89 |
``` cpp
|
| 90 |
-
class B {
|
| 91 |
-
class X : virtual public B {
|
| 92 |
-
class Y : virtual public B {
|
| 93 |
-
class Z : public B {
|
| 94 |
-
class AA : public X, public Y, public Z {
|
| 95 |
```
|
| 96 |
|
| 97 |
For an object of class `AA`, all `virtual` occurrences of base class `B`
|
| 98 |
in the class lattice of `AA` correspond to a single `B` subobject within
|
| 99 |
the object of type `AA`, and every other occurrence of a (non-virtual)
|
| 100 |
base class `B` in the class lattice of `AA` corresponds one-to-one with
|
| 101 |
a distinct `B` subobject within the object of type `AA`. Given the class
|
| 102 |
`AA` defined above, class `AA` has two subobjects of class `B`: `Z`’s
|
| 103 |
-
`B` and the virtual `B` shared by `X` and `Y`, as shown
|
|
|
|
| 104 |
|
| 105 |
<a id="fig:virtnonvirt"></a>
|
| 106 |
|
| 107 |
![Virtual and non-virtual base \[fig:virtnonvirt\]](images/figvirtnonvirt.svg)
|
| 108 |
|
|
|
|
|
|
|
|
|
| 1 |
## Multiple base classes <a id="class.mi">[[class.mi]]</a>
|
| 2 |
|
| 3 |
+
A class can be derived from any number of base classes.
|
| 4 |
+
|
| 5 |
+
[*Note 1*: The use of more than one direct base class is often called
|
| 6 |
+
multiple inheritance. — *end note*]
|
| 7 |
+
|
| 8 |
+
[*Example 1*:
|
| 9 |
|
| 10 |
``` cpp
|
| 11 |
+
class A { ... };
|
| 12 |
+
class B { ... };
|
| 13 |
+
class C { ... };
|
| 14 |
+
class D : public A, public B, public C { ... };
|
| 15 |
```
|
| 16 |
|
| 17 |
+
— *end example*]
|
| 18 |
+
|
| 19 |
+
[*Note 2*: The order of derivation is not significant except as
|
| 20 |
+
specified by the semantics of initialization by constructor (
|
| 21 |
+
[[class.base.init]]), cleanup ([[class.dtor]]), and storage layout (
|
| 22 |
+
[[class.mem]], [[class.access.spec]]). — *end note*]
|
| 23 |
|
| 24 |
A class shall not be specified as a direct base class of a derived class
|
| 25 |
+
more than once.
|
| 26 |
+
|
| 27 |
+
[*Note 3*: A class can be an indirect base class more than once and can
|
| 28 |
+
be a direct and an indirect base class. There are limited things that
|
| 29 |
+
can be done with such a class. The non-static data members and member
|
| 30 |
+
functions of the direct base class cannot be referred to in the scope of
|
| 31 |
+
the derived class. However, the static members, enumerations and types
|
| 32 |
+
can be unambiguously referred to. — *end note*]
|
| 33 |
+
|
| 34 |
+
[*Example 2*:
|
| 35 |
|
| 36 |
``` cpp
|
| 37 |
+
class X { ... };
|
| 38 |
+
class Y : public X, public X { ... }; // ill-formed
|
| 39 |
```
|
| 40 |
|
| 41 |
``` cpp
|
| 42 |
+
class L { public: int next; ... };
|
| 43 |
+
class A : public L { ... };
|
| 44 |
+
class B : public L { ... };
|
| 45 |
+
class C : public A, public B { void f(); ... }; // well-formed
|
| 46 |
+
class D : public A, public L { void f(); ... }; // well-formed
|
| 47 |
```
|
| 48 |
|
| 49 |
+
— *end example*]
|
| 50 |
+
|
| 51 |
+
A base class specifier that does not contain the keyword `virtual`
|
| 52 |
+
specifies a *non-virtual base class*. A base class specifier that
|
| 53 |
+
contains the keyword `virtual` specifies a *virtual base class*. For
|
| 54 |
each distinct occurrence of a non-virtual base class in the class
|
| 55 |
lattice of the most derived class, the most derived object (
|
| 56 |
[[intro.object]]) shall contain a corresponding distinct base class
|
| 57 |
subobject of that type. For each distinct base class that is specified
|
| 58 |
virtual, the most derived object shall contain a single base class
|
| 59 |
+
subobject of that type.
|
| 60 |
+
|
| 61 |
+
[*Note 4*:
|
| 62 |
+
|
| 63 |
+
For an object of class type `C`, each distinct occurrence of a
|
| 64 |
+
(non-virtual) base class `L` in the class lattice of `C` corresponds
|
| 65 |
+
one-to-one with a distinct `L` subobject within the object of type `C`.
|
| 66 |
+
Given the class `C` defined above, an object of class `C` will have two
|
| 67 |
+
subobjects of class `L` as shown in Figure [[fig:nonvirt]].
|
| 68 |
|
| 69 |
<a id="fig:nonvirt"></a>
|
| 70 |
|
| 71 |
![Non-virtual base \[fig:nonvirt\]](images/fignonvirt.svg)
|
| 72 |
|
|
|
|
| 79 |
```
|
| 80 |
|
| 81 |
Without the `A::` or `B::` qualifiers, the definition of `C::f` above
|
| 82 |
would be ill-formed because of ambiguity ([[class.member.lookup]]).
|
| 83 |
|
| 84 |
+
— *end note*]
|
| 85 |
+
|
| 86 |
+
[*Note 5*:
|
| 87 |
+
|
| 88 |
+
In contrast, consider the case with a virtual base class:
|
| 89 |
|
| 90 |
``` cpp
|
| 91 |
+
class V { ... };
|
| 92 |
+
class A : virtual public V { ... };
|
| 93 |
+
class B : virtual public V { ... };
|
| 94 |
+
class C : public A, public B { ... };
|
| 95 |
```
|
| 96 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
<a id="fig:virt"></a>
|
| 98 |
|
| 99 |
![Virtual base \[fig:virt\]](images/figvirt.svg)
|
| 100 |
|
| 101 |
+
For an object `c` of class type `C`, a single subobject of type `V` is
|
| 102 |
+
shared by every base class subobject of `c` that has a `virtual` base
|
| 103 |
+
class of type `V`. Given the class `C` defined above, an object of class
|
| 104 |
+
`C` will have one subobject of class `V`, as shown in Figure
|
| 105 |
+
[[fig:virt]].
|
| 106 |
+
|
| 107 |
+
— *end note*]
|
| 108 |
+
|
| 109 |
+
[*Note 6*:
|
| 110 |
+
|
| 111 |
A class can have both virtual and non-virtual base classes of a given
|
| 112 |
type.
|
| 113 |
|
| 114 |
``` cpp
|
| 115 |
+
class B { ... };
|
| 116 |
+
class X : virtual public B { ... };
|
| 117 |
+
class Y : virtual public B { ... };
|
| 118 |
+
class Z : public B { ... };
|
| 119 |
+
class AA : public X, public Y, public Z { ... };
|
| 120 |
```
|
| 121 |
|
| 122 |
For an object of class `AA`, all `virtual` occurrences of base class `B`
|
| 123 |
in the class lattice of `AA` correspond to a single `B` subobject within
|
| 124 |
the object of type `AA`, and every other occurrence of a (non-virtual)
|
| 125 |
base class `B` in the class lattice of `AA` corresponds one-to-one with
|
| 126 |
a distinct `B` subobject within the object of type `AA`. Given the class
|
| 127 |
`AA` defined above, class `AA` has two subobjects of class `B`: `Z`’s
|
| 128 |
+
`B` and the virtual `B` shared by `X` and `Y`, as shown in Figure
|
| 129 |
+
[[fig:virtnonvirt]].
|
| 130 |
|
| 131 |
<a id="fig:virtnonvirt"></a>
|
| 132 |
|
| 133 |
![Virtual and non-virtual base \[fig:virtnonvirt\]](images/figvirtnonvirt.svg)
|
| 134 |
|
| 135 |
+
— *end note*]
|
| 136 |
+
|