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