102 lines
4.3 KiB
Markdown
102 lines
4.3 KiB
Markdown
[class.free]
|
||
|
||
# 11 Classes [[class]](./#class)
|
||
|
||
## 11.4 Class members [[class.mem]](class.mem#class.free)
|
||
|
||
### 11.4.11 Allocation and deallocation functions [class.free]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2966)
|
||
|
||
Any allocation function for a classT is a static member (even if not explicitly declaredstatic)[.](#1.sentence-1)
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2974)
|
||
|
||
[*Example [1](#example-1)*: class Arena;struct B {void* operator new(std::size_t, Arena*);};struct D1 : B {};
|
||
|
||
Arena* ap;void foo(int i) {new (ap) D1; // calls B::operator new(std::size_t, Arena*)new D1[i]; // calls ::operator new[](std::size_t)new D1; // error: ::operator new(std::size_t) hidden} â *end example*]
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2993)
|
||
|
||
Any deallocation function for a classX is a static member (even if not explicitly declaredstatic)[.](#3.sentence-1)
|
||
|
||
[*Example [2](#example-2)*: class X {void operator delete(void*); void operator delete[](void*, std::size_t);};
|
||
|
||
class Y {void operator delete(void*, std::size_t); void operator delete[](void*);}; â *end example*]
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3014)
|
||
|
||
Since member allocation and deallocation functions arestatic they cannot be virtual[.](#4.sentence-1)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
However, when the[*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") of a[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9 Delete [expr.delete]") refers to an object of class type with a virtual destructor,
|
||
because the deallocation function is chosen by the destructor
|
||
of the dynamic type of the object, the effect is the same in that case[.](#4.sentence-2)
|
||
|
||
[*Example [3](#example-3)*: struct B {virtual ~B(); void operator delete(void*, std::size_t);};
|
||
|
||
struct D : B {void operator delete(void*);};
|
||
|
||
struct E : B {void log_deletion(); void operator delete(E *p, std::destroying_delete_t) { p->log_deletion();
|
||
p->~E(); ::operator delete(p); }};
|
||
|
||
void f() { B* bp = new D; delete bp; // 1: uses D::operator delete(void*) bp = new E; delete bp; // 2: uses E::operator delete(E*, std::destroying_delete_t)}
|
||
|
||
Here, storage for the object of classD is deallocated byD::operator delete(),
|
||
and
|
||
the object of class E is destroyed
|
||
and its storage is deallocated
|
||
by E::operator delete(),
|
||
due to the virtual destructor[.](#4.sentence-3)
|
||
|
||
â *end example*]
|
||
|
||
â *end note*]
|
||
|
||
[*Note [2](#note-2)*:
|
||
|
||
Virtual destructors have no effect on the deallocation function actually
|
||
called when the[*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") of a[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9 Delete [expr.delete]") refers to an array of objects of class type[.](#4.sentence-4)
|
||
|
||
[*Example [4](#example-4)*: struct B {virtual ~B(); void operator delete[](void*, std::size_t);};
|
||
|
||
struct D : B {void operator delete[](void*, std::size_t);};
|
||
|
||
void f(int i) { D* dp = new D[i]; delete [] dp; // uses D::operator delete[](void*, std::size_t) B* bp = new D[i]; delete[] bp; // undefined behavior} â *end example*]
|
||
|
||
â *end note*]
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3092)
|
||
|
||
Access to the deallocation function is checked statically,
|
||
even if a different one is actually executed[.](#5.sentence-1)
|
||
|
||
[*Example [5](#example-5)*:
|
||
|
||
For the call on line â// 1â above,
|
||
ifB::operator delete() had been private, the delete expression would have been ill-formed[.](#5.sentence-2)
|
||
|
||
â *end example*]
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3102)
|
||
|
||
[*Note [3](#note-3)*:
|
||
|
||
If a deallocation function has no explicit [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]"), it
|
||
has a non-throwing exception specification ([[except.spec]](except.spec "14.5 Exception specifications"))[.](#6.sentence-1)
|
||
|
||
â *end note*]
|