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?
"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.
delete this
is not valid in a destructor. It can be used elsewhere. But it's only 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.
The C++ FAQ has an entry about that. C++ Standard quote on my claim above (3.8p5
):
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, for example), detailed at 12.7
.
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.
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.