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; // ill-formed: ::operator new(std::size_t) hidden
} — end example
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
struct B {
virtual ~B();
void operator delete(void*, std::size_t);
};
struct D : B {
void operator delete(void*);
};
void f() {
B* bp = new D;
delete bp; // 1: uses D::operator delete(void*)
}
Here, storage for the non-array object of class
D
is deallocated by
D::operator delete(),
due to the virtual destructor.
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
}