tmp/tmpt3j9xxe2/{from.md → to.md}
RENAMED
|
@@ -1,10 +1,12 @@
|
|
| 1 |
## Free store <a id="class.free">[[class.free]]</a>
|
| 2 |
|
| 3 |
Any allocation function for a class `T` is a static member (even if not
|
| 4 |
explicitly declared `static`).
|
| 5 |
|
|
|
|
|
|
|
| 6 |
``` cpp
|
| 7 |
class Arena;
|
| 8 |
struct B {
|
| 9 |
void* operator new(std::size_t, Arena*);
|
| 10 |
};
|
|
@@ -17,12 +19,14 @@ void foo(int i) {
|
|
| 17 |
new D1[i]; // calls ::operator new[](std::size_t)
|
| 18 |
new D1; // ill-formed: ::operator new(std::size_t) hidden
|
| 19 |
}
|
| 20 |
```
|
| 21 |
|
|
|
|
|
|
|
| 22 |
When an object is deleted with a *delete-expression* ([[expr.delete]]),
|
| 23 |
-
a
|
| 24 |
`operator delete[]()` for arrays) is (implicitly) called to reclaim the
|
| 25 |
storage occupied by the object ([[basic.stc.dynamic.deallocation]]).
|
| 26 |
|
| 27 |
Class-specific deallocation function lookup is a part of general
|
| 28 |
deallocation function lookup ([[expr.delete]]) and occurs as follows.
|
|
@@ -39,10 +43,12 @@ inaccessible, or if the lookup selects a placement deallocation
|
|
| 39 |
function, the program is ill-formed.
|
| 40 |
|
| 41 |
Any deallocation function for a class `X` is a static member (even if
|
| 42 |
not explicitly declared `static`).
|
| 43 |
|
|
|
|
|
|
|
| 44 |
``` cpp
|
| 45 |
class X {
|
| 46 |
void operator delete(void*);
|
| 47 |
void operator delete[](void*, std::size_t);
|
| 48 |
};
|
|
@@ -51,16 +57,22 @@ class Y {
|
|
| 51 |
void operator delete(void*, std::size_t);
|
| 52 |
void operator delete[](void*);
|
| 53 |
};
|
| 54 |
```
|
| 55 |
|
|
|
|
|
|
|
| 56 |
Since member allocation and deallocation functions are `static` they
|
| 57 |
-
cannot be virtual.
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
|
| 63 |
``` cpp
|
| 64 |
struct B {
|
| 65 |
virtual ~B();
|
| 66 |
void operator delete(void*, std::size_t);
|
|
@@ -75,14 +87,19 @@ void f() {
|
|
| 75 |
delete bp; // 1: uses D::operator delete(void*)
|
| 76 |
}
|
| 77 |
```
|
| 78 |
|
| 79 |
Here, storage for the non-array object of class `D` is deallocated by
|
| 80 |
-
`D::operator delete()`, due to the virtual destructor.
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
|
| 85 |
``` cpp
|
| 86 |
struct B {
|
| 87 |
virtual ~B();
|
| 88 |
void operator delete[](void*, std::size_t);
|
|
@@ -98,15 +115,19 @@ void f(int i) {
|
|
| 98 |
B* bp = new D[i];
|
| 99 |
delete[] bp; // undefined behavior
|
| 100 |
}
|
| 101 |
```
|
| 102 |
|
|
|
|
|
|
|
| 103 |
Access to the deallocation function is checked statically. Hence, even
|
| 104 |
though a different one might actually be executed, the statically
|
| 105 |
-
visible deallocation function is required to be accessible.
|
| 106 |
-
on line //1 above, if `B::operator delete()` had been `private`, the
|
| 107 |
-
delete expression would have been ill-formed.
|
| 108 |
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
|
|
|
|
| 1 |
## Free store <a id="class.free">[[class.free]]</a>
|
| 2 |
|
| 3 |
Any allocation function for a class `T` is a static member (even if not
|
| 4 |
explicitly declared `static`).
|
| 5 |
|
| 6 |
+
[*Example 1*:
|
| 7 |
+
|
| 8 |
``` cpp
|
| 9 |
class Arena;
|
| 10 |
struct B {
|
| 11 |
void* operator new(std::size_t, Arena*);
|
| 12 |
};
|
|
|
|
| 19 |
new D1[i]; // calls ::operator new[](std::size_t)
|
| 20 |
new D1; // ill-formed: ::operator new(std::size_t) hidden
|
| 21 |
}
|
| 22 |
```
|
| 23 |
|
| 24 |
+
— *end example*]
|
| 25 |
+
|
| 26 |
When an object is deleted with a *delete-expression* ([[expr.delete]]),
|
| 27 |
+
a deallocation function (`operator delete()` for non-array objects or
|
| 28 |
`operator delete[]()` for arrays) is (implicitly) called to reclaim the
|
| 29 |
storage occupied by the object ([[basic.stc.dynamic.deallocation]]).
|
| 30 |
|
| 31 |
Class-specific deallocation function lookup is a part of general
|
| 32 |
deallocation function lookup ([[expr.delete]]) and occurs as follows.
|
|
|
|
| 43 |
function, the program is ill-formed.
|
| 44 |
|
| 45 |
Any deallocation function for a class `X` is a static member (even if
|
| 46 |
not explicitly declared `static`).
|
| 47 |
|
| 48 |
+
[*Example 2*:
|
| 49 |
+
|
| 50 |
``` cpp
|
| 51 |
class X {
|
| 52 |
void operator delete(void*);
|
| 53 |
void operator delete[](void*, std::size_t);
|
| 54 |
};
|
|
|
|
| 57 |
void operator delete(void*, std::size_t);
|
| 58 |
void operator delete[](void*);
|
| 59 |
};
|
| 60 |
```
|
| 61 |
|
| 62 |
+
— *end example*]
|
| 63 |
+
|
| 64 |
Since member allocation and deallocation functions are `static` they
|
| 65 |
+
cannot be virtual.
|
| 66 |
+
|
| 67 |
+
[*Note 1*:
|
| 68 |
+
|
| 69 |
+
However, when the *cast-expression* of a *delete-expression* refers to
|
| 70 |
+
an object of class type, because the deallocation function actually
|
| 71 |
+
called is looked up in the scope of the class that is the dynamic type
|
| 72 |
+
of the object, if the destructor is virtual, the effect is the same. For
|
| 73 |
+
example,
|
| 74 |
|
| 75 |
``` cpp
|
| 76 |
struct B {
|
| 77 |
virtual ~B();
|
| 78 |
void operator delete(void*, std::size_t);
|
|
|
|
| 87 |
delete bp; // 1: uses D::operator delete(void*)
|
| 88 |
}
|
| 89 |
```
|
| 90 |
|
| 91 |
Here, storage for the non-array object of class `D` is deallocated by
|
| 92 |
+
`D::operator delete()`, due to the virtual destructor.
|
| 93 |
+
|
| 94 |
+
— *end note*]
|
| 95 |
+
|
| 96 |
+
[*Note 2*:
|
| 97 |
+
|
| 98 |
+
Virtual destructors have no effect on the deallocation function actually
|
| 99 |
+
called when the *cast-expression* of a *delete-expression* refers to an
|
| 100 |
+
array of objects of class type. For example,
|
| 101 |
|
| 102 |
``` cpp
|
| 103 |
struct B {
|
| 104 |
virtual ~B();
|
| 105 |
void operator delete[](void*, std::size_t);
|
|
|
|
| 115 |
B* bp = new D[i];
|
| 116 |
delete[] bp; // undefined behavior
|
| 117 |
}
|
| 118 |
```
|
| 119 |
|
| 120 |
+
— *end note*]
|
| 121 |
+
|
| 122 |
Access to the deallocation function is checked statically. Hence, even
|
| 123 |
though a different one might actually be executed, the statically
|
| 124 |
+
visible deallocation function is required to be accessible.
|
|
|
|
|
|
|
| 125 |
|
| 126 |
+
[*Example 3*: For the call on line “// 1” above, if
|
| 127 |
+
`B::operator delete()` had been `private`, the delete expression would
|
| 128 |
+
have been ill-formed. — *end example*]
|
| 129 |
+
|
| 130 |
+
[*Note 3*: If a deallocation function has no explicit
|
| 131 |
+
*noexcept-specifier*, it has a non-throwing exception specification (
|
| 132 |
+
[[except.spec]]). — *end note*]
|
| 133 |
|