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