[class.free] (original) (raw)
11 Classes [class]
11.12 Free store [class.free]
Any allocation function for a classTis 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; new D1[i]; new D1; } — _end example_]
Class-specific deallocation function lookup is a part of general deallocation function lookup ([expr.delete]) and occurs as follows.
If the delete-expressionis used to deallocate a class object whose static type has a virtual destructor, the deallocation function is the one selected at the point of definition of the dynamic type's virtual destructor ([class.dtor]).119
Otherwise, if thedelete-expressionis used to deallocate an object of classTor array thereof, the deallocation function's name is looked up in the scope ofT.
If this lookup fails to find the name, general deallocation function lookup ([expr.delete]) continues.
If the result of the lookup is ambiguous or inaccessible, or if the lookup selects a placement deallocation function, the program is ill-formed.
Any deallocation function for a classXis 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[](void*);}; — _end example_]
Since member allocation and deallocation functions arestaticthey cannot be virtual.
[Note 1:
However, when thecast-expressionof adelete-expressionrefers to an object of class type, because the deallocation function actually called is looked up in the scope of the class that is the dynamic type of the object if the destructor is virtual, the effect is the same in that case.
For example,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; bp = new E;delete bp; }
Here, storage for the object of classDis 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 note_]
[Note 2:
Virtual destructors have no effect on the deallocation function actually called when thecast-expressionof adelete-expressionrefers to an array of objects of class type.
For example,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; B* bp = new D[i];delete[] bp; }
— _end note_]
Access to the deallocation function is checked statically.
[Note 3:
Hence, even though a different one might actually be executed, the statically visible deallocation function is required to be accessible.
— _end note_]
[Example 3:
For the call on line “// 1” above, ifB::operator delete()had been private, the delete expression would have been ill-formed.
— _end example_]