tmp/tmpxd7yrvoa/{from.md → to.md}
RENAMED
|
@@ -21,12 +21,12 @@ parentheses, and the *id-expression* has one of the following forms:
|
|
| 21 |
`~`*class-name* and the *class-name* is the injected-class-name of the
|
| 22 |
class nominated by the *nested-name-specifier*.
|
| 23 |
|
| 24 |
A prospective destructor shall take no arguments [[dcl.fct]]. Each
|
| 25 |
*decl-specifier* of the *decl-specifier-seq* of a prospective destructor
|
| 26 |
-
declaration (if any) shall be `friend`, `inline`, `virtual`,
|
| 27 |
-
`constexpr`
|
| 28 |
|
| 29 |
If a class has no user-declared prospective destructor, a prospective
|
| 30 |
destructor is implicitly declared as defaulted [[dcl.fct.def]]. An
|
| 31 |
implicitly-declared prospective destructor is an inline public member of
|
| 32 |
its class.
|
|
@@ -59,33 +59,39 @@ when the destructor for the most derived object [[intro.object]] starts.
|
|
| 59 |
|
| 60 |
[*Note 2*: A declaration of a destructor that does not have a
|
| 61 |
*noexcept-specifier* has the same exception specification as if it had
|
| 62 |
been implicitly declared [[except.spec]]. — *end note*]
|
| 63 |
|
| 64 |
-
A defaulted destructor for a class `X` is defined as deleted if
|
| 65 |
|
| 66 |
-
- `X` is a
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
function results in an ambiguity or in a function that is deleted or
|
| 73 |
inaccessible from the defaulted destructor.
|
| 74 |
|
| 75 |
-
A destructor is trivial if it is not user-provided and
|
|
|
|
| 76 |
|
| 77 |
- the destructor is not virtual,
|
| 78 |
-
- all of the direct base classes of
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
|
| 83 |
Otherwise, the destructor is *non-trivial*.
|
| 84 |
|
| 85 |
-
A defaulted destructor is a constexpr destructor
|
| 86 |
-
constexpr-suitable [[dcl.constexpr]].
|
| 87 |
|
| 88 |
Before a defaulted destructor for a class is implicitly defined, all the
|
| 89 |
non-user-provided destructors for its base classes and its non-static
|
| 90 |
data members are implicitly defined.
|
| 91 |
|
|
@@ -98,17 +104,18 @@ created in the program, the destructor shall be defined.
|
|
| 98 |
during destruction; see [[class.cdtor]]. — *end note*]
|
| 99 |
|
| 100 |
After executing the body of the destructor and destroying any objects
|
| 101 |
with automatic storage duration allocated within the body, a destructor
|
| 102 |
for class `X` calls the destructors for `X`’s direct non-variant
|
| 103 |
-
non-static data members, the destructors for
|
| 104 |
-
base classes and, if `X` is the most derived
|
| 105 |
-
its destructor calls the destructors for
|
| 106 |
-
destructors are called as if they were
|
| 107 |
-
that is, ignoring any possible virtual
|
| 108 |
-
derived classes. Bases and members are
|
| 109 |
-
the completion of their constructor
|
|
|
|
| 110 |
|
| 111 |
[*Note 4*: A `return` statement [[stmt.return]] in a destructor might
|
| 112 |
not directly return to the caller; before transferring control to the
|
| 113 |
caller, the destructors for the members and bases are
|
| 114 |
called. — *end note*]
|
|
@@ -154,11 +161,11 @@ lookup fails or if the deallocation function has a deleted definition
|
|
| 154 |
[*Note 6*: This assures that a deallocation function corresponding to
|
| 155 |
the dynamic type of an object is available for the *delete-expression*
|
| 156 |
[[class.free]]. — *end note*]
|
| 157 |
|
| 158 |
In an explicit destructor call, the destructor is specified by a `~`
|
| 159 |
-
followed by a *type-name* or *
|
| 160 |
destructor’s class type. The invocation of a destructor is subject to
|
| 161 |
the usual rules for member functions [[class.mfct]]; that is, if the
|
| 162 |
object is not of the destructor’s class type and not of a class derived
|
| 163 |
from the destructor’s class type (including when the destructor is
|
| 164 |
invoked via a null pointer value), the program has undefined behavior.
|
|
@@ -201,11 +208,13 @@ member function is not an explicit destructor call
|
|
| 201 |
|
| 202 |
Explicit calls of destructors are rarely needed. One use of such calls
|
| 203 |
is for objects placed at specific addresses using a placement
|
| 204 |
*new-expression*. Such use of explicit placement and destruction of
|
| 205 |
objects can be necessary to cope with dedicated hardware resources and
|
| 206 |
-
for writing memory management facilities.
|
|
|
|
|
|
|
| 207 |
|
| 208 |
``` cpp
|
| 209 |
void* operator new(std::size_t, void* p) { return p; }
|
| 210 |
struct X {
|
| 211 |
X(int);
|
|
@@ -219,17 +228,19 @@ void g() { // rare, specialized use:
|
|
| 219 |
f(p);
|
| 220 |
p->X::~X(); // cleanup
|
| 221 |
}
|
| 222 |
```
|
| 223 |
|
|
|
|
|
|
|
| 224 |
— *end note*]
|
| 225 |
|
| 226 |
Once a destructor is invoked for an object, the object’s lifetime ends;
|
| 227 |
the behavior is undefined if the destructor is invoked for an object
|
| 228 |
whose lifetime has ended [[basic.life]].
|
| 229 |
|
| 230 |
-
[*Example
|
| 231 |
duration is explicitly invoked, and the block is subsequently left in a
|
| 232 |
manner that would ordinarily invoke implicit destruction of the object,
|
| 233 |
the behavior is undefined. — *end example*]
|
| 234 |
|
| 235 |
[*Note 10*:
|
|
|
|
| 21 |
`~`*class-name* and the *class-name* is the injected-class-name of the
|
| 22 |
class nominated by the *nested-name-specifier*.
|
| 23 |
|
| 24 |
A prospective destructor shall take no arguments [[dcl.fct]]. Each
|
| 25 |
*decl-specifier* of the *decl-specifier-seq* of a prospective destructor
|
| 26 |
+
declaration (if any) shall be `friend`, `inline`, `virtual`, or
|
| 27 |
+
`constexpr`.
|
| 28 |
|
| 29 |
If a class has no user-declared prospective destructor, a prospective
|
| 30 |
destructor is implicitly declared as defaulted [[dcl.fct.def]]. An
|
| 31 |
implicitly-declared prospective destructor is an inline public member of
|
| 32 |
its class.
|
|
|
|
| 59 |
|
| 60 |
[*Note 2*: A declaration of a destructor that does not have a
|
| 61 |
*noexcept-specifier* has the same exception specification as if it had
|
| 62 |
been implicitly declared [[except.spec]]. — *end note*]
|
| 63 |
|
| 64 |
+
A defaulted destructor for a class `X` is defined as deleted if
|
| 65 |
|
| 66 |
+
- `X` is a non-union class and any non-variant potentially constructed
|
| 67 |
+
subobject has class type `M` (or possibly multidimensional array
|
| 68 |
+
thereof) where `M` has a destructor that is deleted or is inaccessible
|
| 69 |
+
from the defaulted destructor,
|
| 70 |
+
- `X` is a union and
|
| 71 |
+
- overload resolution to select a constructor to default-initialize an
|
| 72 |
+
object of type `X` either fails or selects a constructor that is
|
| 73 |
+
either deleted or not trivial, or
|
| 74 |
+
- `X` has a variant member `V` of class type `M` (or possibly
|
| 75 |
+
multi-dimensional array thereof) where `V` has a default member
|
| 76 |
+
initializer and `M` has a destructor that is non-trivial, or,
|
| 77 |
+
- for a virtual destructor, lookup of the non-array deallocation
|
| 78 |
function results in an ambiguity or in a function that is deleted or
|
| 79 |
inaccessible from the defaulted destructor.
|
| 80 |
|
| 81 |
+
A destructor for a class `X` is trivial if it is not user-provided and
|
| 82 |
+
if
|
| 83 |
|
| 84 |
- the destructor is not virtual,
|
| 85 |
+
- all of the direct base classes of `X` have trivial destructors, and
|
| 86 |
+
- either `X` is a union or for all of the non-variant non-static data
|
| 87 |
+
members of `X` that are of class type (or array thereof), each such
|
| 88 |
+
class has a trivial destructor.
|
| 89 |
|
| 90 |
Otherwise, the destructor is *non-trivial*.
|
| 91 |
|
| 92 |
+
A defaulted destructor is a constexpr destructor.
|
|
|
|
| 93 |
|
| 94 |
Before a defaulted destructor for a class is implicitly defined, all the
|
| 95 |
non-user-provided destructors for its base classes and its non-static
|
| 96 |
data members are implicitly defined.
|
| 97 |
|
|
|
|
| 104 |
during destruction; see [[class.cdtor]]. — *end note*]
|
| 105 |
|
| 106 |
After executing the body of the destructor and destroying any objects
|
| 107 |
with automatic storage duration allocated within the body, a destructor
|
| 108 |
for class `X` calls the destructors for `X`’s direct non-variant
|
| 109 |
+
non-static data members other than anonymous unions, the destructors for
|
| 110 |
+
`X`’s non-virtual direct base classes and, if `X` is the most derived
|
| 111 |
+
class [[class.base.init]], its destructor calls the destructors for
|
| 112 |
+
`X`’s virtual base classes. All destructors are called as if they were
|
| 113 |
+
referenced with a qualified name, that is, ignoring any possible virtual
|
| 114 |
+
overriding destructors in more derived classes. Bases and members are
|
| 115 |
+
destroyed in the reverse order of the completion of their constructor
|
| 116 |
+
(see [[class.base.init]]).
|
| 117 |
|
| 118 |
[*Note 4*: A `return` statement [[stmt.return]] in a destructor might
|
| 119 |
not directly return to the caller; before transferring control to the
|
| 120 |
caller, the destructors for the members and bases are
|
| 121 |
called. — *end note*]
|
|
|
|
| 161 |
[*Note 6*: This assures that a deallocation function corresponding to
|
| 162 |
the dynamic type of an object is available for the *delete-expression*
|
| 163 |
[[class.free]]. — *end note*]
|
| 164 |
|
| 165 |
In an explicit destructor call, the destructor is specified by a `~`
|
| 166 |
+
followed by a *type-name* or *computed-type-specifier* that denotes the
|
| 167 |
destructor’s class type. The invocation of a destructor is subject to
|
| 168 |
the usual rules for member functions [[class.mfct]]; that is, if the
|
| 169 |
object is not of the destructor’s class type and not of a class derived
|
| 170 |
from the destructor’s class type (including when the destructor is
|
| 171 |
invoked via a null pointer value), the program has undefined behavior.
|
|
|
|
| 208 |
|
| 209 |
Explicit calls of destructors are rarely needed. One use of such calls
|
| 210 |
is for objects placed at specific addresses using a placement
|
| 211 |
*new-expression*. Such use of explicit placement and destruction of
|
| 212 |
objects can be necessary to cope with dedicated hardware resources and
|
| 213 |
+
for writing memory management facilities.
|
| 214 |
+
|
| 215 |
+
[*Example 2*:
|
| 216 |
|
| 217 |
``` cpp
|
| 218 |
void* operator new(std::size_t, void* p) { return p; }
|
| 219 |
struct X {
|
| 220 |
X(int);
|
|
|
|
| 228 |
f(p);
|
| 229 |
p->X::~X(); // cleanup
|
| 230 |
}
|
| 231 |
```
|
| 232 |
|
| 233 |
+
— *end example*]
|
| 234 |
+
|
| 235 |
— *end note*]
|
| 236 |
|
| 237 |
Once a destructor is invoked for an object, the object’s lifetime ends;
|
| 238 |
the behavior is undefined if the destructor is invoked for an object
|
| 239 |
whose lifetime has ended [[basic.life]].
|
| 240 |
|
| 241 |
+
[*Example 3*: If the destructor for an object with automatic storage
|
| 242 |
duration is explicitly invoked, and the block is subsequently left in a
|
| 243 |
manner that would ordinarily invoke implicit destruction of the object,
|
| 244 |
the behavior is undefined. — *end example*]
|
| 245 |
|
| 246 |
[*Note 10*:
|