What is the use of "delete this"?
Asked Answered
S

4

30

Today, I have seen some legacy code. In the destructor there is a statement like "delete this". I think, this call will be recursive. Why it is working?

I made some quick search on Y!, I found that if there is a need to restrict the user to create the stack object, we can make destructor private and provide an interface to delete the instance. In the interface provided, we have to call delete on this pointer.

Are there any other situations for using such statements?

Shutt answered 15/1, 2009 at 16:11 Comment(0)
H
34

"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.

Haihaida answered 15/1, 2009 at 16:16 Comment(3)
While self-deletion of refcounted objects is a very common pattern, I think the original question was about putting it in a destructor, not a Release() function, in which case it's just insane.Gatewood
@rmeador, There are really two questions. Both the title and last sentence suggest wanting to know valid uses of "delete this;". I hope I answered that. The middle does suggest a question of "why delete this in a dtor". I agree to do so appears to be insane.Haihaida
Your sample code has a bug. If _refCount is a member variable, when you "delete this" that member variable no longer exists, so your "return _refCount" line has undefined behaviour.Crookes
O
25

delete this is valid in C++11

It is valid to call delete this in a destructor. The C++ FAQ has an entry about that. The restrictions of C++11 [basic.life] p5 do not apply to objects under destruction, and C++11 [class.cdtor] does not restrict you from using delete this.

Despite being valid, it's rarely a good idea. The wxWidgets framework uses it for their thread class. It has a mode where, when the thread ends execution, it automatically frees system resources and itself (the wxThread object). I found it very annoying, because from outside, you can't know whether it's valid to refer it or not - you can't call a function like IsValid anymore, because the object doesn't exist. That smells like the main problem with delete this, apart from the problem that it can't be used for non-dynamic objects.

If you do it, make sure you don't touch any data-member, or call any member function anymore on the object you deleted that way. Best do it as the last statement in a non-virtual, protected or private function. Calling delete is valid in a virtual and/or public function too, but i would restrict the visibility of the method doing that.


Note: delete this may not be used in a destructor as per C++11 [class.dtor] p15, and you have to avoid destroying an object twice.

delete this used to be undefined behavior in C++03

C++ Standard quote on my claim above (C++03 [basic.life] p5):

Before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that refers to the storage location where the object will be or was located may be used but only in limited ways. [...] If the object will be or was of a class type with a non-trivial destructor, and the pointer is used as the operand of a delete-expression, the program has undefined behavior.

Lifetime ends when the destructor of the object begins execution. Note there are exceptions to the rules coming after that paragraph for objects under construction and destruction (you are allowed to access non-static data members of POD types, for example), detailed at C++03 [class.cdtor].

Oxidase answered 15/1, 2009 at 16:44 Comment(0)
R
3

There where considered to be good reasons to do this in the early C++ days. For example the self delete of a ref counted object (as JaredPar says). As far as I know they have all been found to be a bad idea in the long run.

Robinrobina answered 15/1, 2009 at 17:6 Comment(3)
exactly what i think. today if i would need to write a ref counted object, i would keep data in an extra object, and make the host object (the one that is copied around) delete the wrapped data when reference count drops to zero. self deleting smells :)Oxidase
@Johannes Schaub - litb: Completely agree; an object responsible for its responsibilities and deciding when to clean itself up? Yucky!Icterus
@JohannesSchaub-litb then the host object has to self-delete when it is done instead...Transmission
T
2

In a doubly-linked list, it's possible to remove a node without referencing any outside structure, such as the high-level "list" object. This makes it reasonable for each node to handle its own deallocation (potentially coupled with a complementary static method to handle the initial allocation from the same pool of memory). In this situation, it could make sense for the node object to delete itself (when requested by the user).

void RemoveAndDeallocate()
{
    LinkedListNode *current_prev = prev, *current_next = next;
    current_prev->next = current_next;
    current_next->prev = current_prev;
    delete this;
}

Although, it's also reasonable for a node to be unlinked from one list and linked into another list, without deallocating any memory, so it's not desirable for a single remove operation to unconditionally free the memory.

Transfer answered 30/1, 2010 at 2:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.