Files
2025-10-25 03:02:53 +03:00

102 lines
4.3 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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*]