Reputation: 1701
In "Effective C++" Item 52:Write placement delete if you write placement new.
Meyers says that for Widget *pw = new (std::cerr) Widget;
, placement new will be invoked. But if placement new doesn't throw exception, and we get to a delete in client code: delete pw;
. Then, this delete
will only invoke the normal delete, not the placement delete.
Meyers then comes to the conclusion that you must provide the normal operator delete. So, what should this normal operator delete looks like? I think the inside of this normal operator delete should resemble the placement delete.
But if I use a normal operator new instead of placement new to create an object Widget *pw = new Widget;
, and use delete pw
afterwards, then it will also call the normal operator delete I wrote for placement new. But this does not seems to be right.
Upvotes: 0
Views: 114
Reputation: 1701
You don't need to write a normal operator delete that resembles the placement delete.
Instead, when you want to delete an object created by placement new,you have to call placement delete through Widget::delete(pw, std::cerr)
.You shouldn't call delete pw
directly,if you do it this way, the compiler will complain.In vs2013, the compiler will output
cannot delete pointers to objects of this type; the class has no non-placement overload for 'operator delete'
So,no need to worry about placement delete in normal operator delete.
Upvotes: 0
Reputation: 10998
Something like this:
struct Widget {
Widget() { throw std::runtime_error(""); }
// custom placement new
static void* operator new(std::size_t sz, const std::string& msg) {
std::cout << "custom placement new called, msg = " << msg << '\n';
return ::operator new(sz);
}
// custom placement delete
static void operator delete(void* ptr, const std::string& msg)
{
std::cout << "custom placement delete called, msg = " << msg << '\n';
::operator delete(ptr);
}
};
int main()
{
try {
Widget* p1 = new ("widget") Widget;
}
catch(const std::exception& e) {
std::cout << e.what() << '\n';
}
}
Upvotes: 2