Tim_King
Tim_King

Reputation: 135

Is destructor called implicitly in a overloaded operator delete function?

I have class Item which defines its own operator new and operator delete as follows:

class Item
{
public:
    Item(const std::string &s):msg(s)
    {
        std::cout<<"Ctor: "<<msg<<std::endl;
    }
    static void* operator new(size_t size, int ID, const std::string &extra)
    {
        std::cout<<"My Operator New. ID/extra: "<<ID<<"/"<<extra<<std::endl;
        return ::operator new(size);
    }
    static void operator delete(void* p)
    {
        std::cout<<"My Operator Delete"<<std::endl;
        return;
    }
    ~Item()
    {
        std::cout<<"Destructor: "<<msg<<std::endl;
    }
    void Print()
    {
        std::cout<<"Item::msg: "<<msg<<std::endl;
    }
private:
    std::string msg;
};

I create an object of this type by using a placement new and then delete as follows:

int main()
{
    Item *pI=new(1,"haha")Item("AC Milan");
    std::cout<<"before delete"<<std::endl;
    delete pI;
    std::cout<<"after delete"<<std::endl;
    return 0;
}

The output is:

My Operator New. ID/extra: 1/haha
Ctor: AC Milan
before delete
Destructor: AC Milan
My Operator Delete
after delete

As you can see, delete pI calls my own delete function in which nothing is done except outputting a log. However, from the output, the destructor of Item is called in delete pI which isn't invoked in my own delete function.

So in this case, destructor would be called implicitly in a overloaded delete function?

Upvotes: 9

Views: 1585

Answers (3)

Peter
Peter

Reputation: 36617

The destructor is not called by an overloaded operator delete() function.

However, a delete expression (in your case, delete pI) has the effect of first invoking the destructor for the object, and then calling the appropriate overload of operator delete().

Upvotes: 3

dascandy
dascandy

Reputation: 7302

So in this case, destructor would be called implicitly in a overloaded delete function?

Destructors and overloaded delete operators interact in a complicated way. When you say

delete pI;

this actually compiles to an invocation of your destructor, and no reference is made to "delete".

Your destructor has (GCC) two instances in the VTable (if virtual), or (MSVC) a boolean argument. The instances / bool are used to determine whether the destructor so compiled should be a deleting, or a non-deleting destructor call. As you can guess, the deleting destructor is then responsible for calling the link-time operator delete for you. If you'd have written

pI->~Item();

you would have compiled to running the non-deleting destructor (the other vtable entry, or with the boolean flipped).

Since your destructor is nonvirtual, it's probably all inlined anyway. The behaviour will be indistinguishable from this though. This is how, if your destructor is virtual, the delete will invoke the right delete for whatever type you actually have, rather than the delete of the pointer type on which you call delete.

Upvotes: 0

songyuanyao
songyuanyao

Reputation: 173024

So in this case, destructor would be called implicitly in a overloaded delete function?

Yes. For a delete expression, (1)the destructor will be invoked firstly, then (2)the apporiate operator delete will be invoked; name lookup and overload resolution will be performed at this stage.

If expression is not a null pointer, the delete expression invokes the destructor (if any) for the object that's being destroyed, or for every element of the array being destroyed (proceeding from the last element to the first element of the array).

After that, unless the matching new-expression was combined with another new-expression (since C++14) the delete expression invokes the deallocation function, either operator delete (for the first version of the expression) or operator delete[] (for the second version of the expression).

Upvotes: 7

Related Questions