Yuan Wen
Yuan Wen

Reputation: 1701

If I write a placement new?How should I write normal operator delete?

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

Answers (2)

Yuan Wen
Yuan Wen

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

Andreas DM
Andreas DM

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

Related Questions