What Is the Use of "Delete This"

What is the use of delete this?

"delete this" is commonly used for ref counted objects. For a ref counted object the decision of when to delete is usually placed on the object itself. Here is an example of what a Release method would look like [1].

int MyRefCountedObject::Release() {
_refCount--;
if ( 0 == _refCount ) {
delete this;
return 0;
}
return _refCount;
}

ATL COM objects are a prime example of this pattern.

[1] Yes I realize this is not thread safe.

Is it OK to use delete this to delete the current object?

If the Node destructor is being called, then it's already in the process of being deleted. So a delete doesn't make sense inside your Node destructor.

Also this is wrong:

while (temp->next() != NULL)
{
delete temp;
temp = temp->next();
}

Instead you should get temp->next() into a temp variable. Otherwise you are accessing deleted memory.

So more like this:

DoublyLinkedList::~DoublyLinkedList
{
Node *temp = first();
while (temp != NULL)
{
Node *temp2 = temp->next();
delete temp;
temp = temp2;
}
}

delete (this) pointer in destructor

this->~destructor is called, then delete(this) will will again call this->~destructor thus results in calling function indefinitely.

Is delete this allowed in C++?

The C++ FAQ Lite has a entry specifically for this

  • https://isocpp.org/wiki/faq/freestore-mgmt#delete-this

I think this quote sums it up nicely

As long as you're careful, it's OK for an object to commit suicide (delete this).

Is delete this a bad idea?

The FAQlite answers this quite well:

As long as you're careful, it's OK for
an object to commit suicide (delete
this).

Here's how I define "careful":

  1. You must be absolutely 100% positive sure that this object was
    allocated via new (not by new[], nor
    by placement new, nor a local object
    on the stack, nor a global, nor a
    member of another object; but by plain
    ordinary new).
  2. You must be absolutely 100% positive sure that your member
    function will be the last member
    function invoked on this object.
  3. You must be absolutely 100% positive sure that the rest of your
    member function (after the delete this
    line) doesn't touch any piece of this
    object (including calling any other
    member functions or touching any data
    members).
  4. You must be absolutely 100% positive sure that no one even touches
    the this pointer itself after the
    delete this line. In other words, you
    must not examine it, compare it with
    another pointer, compare it with NULL,
    print it, cast it, do anything with
    it.

Naturally the usual caveats apply in
cases where your this pointer is a
pointer to a base class when you don't
have a virtual destructor.

Basically, you need to take the same care as you do with deleteing any other pointer. However, there are more areas where things can go wrong with a member function committing suicide, compared with an explicitly-declared pointer.

Should delete this be called from within a member method?

Normally this is a bad idea, but it's occasionally useful.

It's perfectly safe as long as you don't use any member variables after you delete, and as long as clients calling this method understand it may delete the object.

A good example of when this is useful is if your class employs reference counting:

void Ref() {
m_References++;
}

void Deref() {
m_References--;
if (m_References == 0) {
delete this;
}
}

Usefulness of 'delete this' in member function

Generally speaking, it's a bad idea as you're technically inside a member function when you do it and suddenly every member of that class is now invalid. Obviously if you do not touch anything after the delete this; call, you'll be okay. But it's very easy to forget these things, try and access a member variable and get undefined behavior and spend time at the debugger.

That said, it's used in things like Microsoft's Component Object Model (COM), when releasing a component (NOTE, this isn't exactly what they do as CashCow points out and is for illustrative purposes only):

void AddRef() { m_nRefs++; }
void Release()
{
m_nRefs--;
if(m_nRefs == 0)
delete this;
// class member-variables now deallocated, accessing them is undefined behaviour!
} // eo Release

That said, in C++ we have smart pointers (such as boost::shared_ptr) to manage the lifetimes of objects for us. Given that COM is inter-process and accessible from languages such as VB, smart pointers were not an option for the design team.

What does delete command really do for memory, for pointers in C++?

Think of memory as a big warehouse with lots of boxes to put things into. When you call "new", the warehouse staff finds an unused box large enough for your needs, records that box as being owned by you (so it's not given to someone else), and gives you the number of that box so you can put your stuff into it. This number would be the "pointer".

Now, when you "delete" that pointer, the reverse happens: the warehouse staff notes that this particular box is available again. Contrary to real warehouse staff they aren't doing anything with the box — so if you look into it after a "delete" you might see your old stuff. Or you might see somebody else’s stuff, if the box was reassigned in the meantime.

Technically, you are not allowed to look into your box once you have returned it to the pool, but this is a somewhat weird warehouse with no keys or guards, so you can still do whatever you want. However, it might cause problems with the new owner of the box, so it's expected that you follow the rules.



Related Topics



Leave a reply



Submit