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

101
cppdraft/class/free.md Normal file
View File

@@ -0,0 +1,101 @@
[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.3Explicit type conversion (cast notation)[expr.cast]") of a[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[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.3Explicit type conversion (cast notation)[expr.cast]") of a[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[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.5Exception specifications[except.spec]"), it
has a non-throwing exception specification ([[except.spec]](except.spec "14.5Exception specifications"))[.](#6.sentence-1)
— *end note*]