4.3 KiB
[class.free]
11 Classes [class]
11.4 Class members [class.mem]
11.4.11 Allocation and deallocation functions [class.free]
Any allocation function for a classT is a static member (even if not explicitly declaredstatic).
[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 newnew D1; // error: ::operator new(std::size_t) hidden} â end example]
Any deallocation function for a classX is a static member (even if not explicitly declaredstatic).
[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;}; â end example]
Since member allocation and deallocation functions arestatic they cannot be virtual.
[Note 1:
However, when thecast-expression of adelete-expression 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.
[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.
â end example]
â end note]
[Note 2:
Virtual destructors have no effect on the deallocation function actually called when thecast-expression of adelete-expression refers to an array of objects of class type.
[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]
Access to the deallocation function is checked statically, even if a different one is actually executed.
[Example 5:
For the call on line â// 1â above, ifB::operator delete() had been private, the delete expression would have been ill-formed.
â end example]
[Note 3:
If a deallocation function has no explicit noexcept-specifier, it has a non-throwing exception specification ([except.spec]).
â end note]