this-delete

Started by
3 comments, last by MaulingMonkey 17 years, 12 months ago
What happens if I do "delete this;" inside a function? will it erase itself? Thanks.
"We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the internet, we know this is not true." -- Professor Robert Silensky
Advertisement
Yes the object deletes itself.

As long as you don't access any member variables of the object you just deleted, you'll be okay. This happens a lot in reference-counted memory systems:

			long release_()			{				if ( !--m_refCount )				{					on_final_release();					delete this;					return 0;				}				return m_refCount;			}


Note how in this method after the object deletes itself it returns 0 instead of returning the value of m_refCount, even though it was zero. This is because m_refCount doesn't exist anymore.
Yes. Think of the member function as a non-member function that takes this explicitly:
void F(Obj* this) {  // do whatever with this  delete this;}

The function will delete the this argument, then finish executing. There are some things you have to be careful of when using delete this. It's generally not recommended.
Yeah - you also have to be aware of destruction order, and that delete only returns after the object is completely destroyed. Destruction starts at the 'top' and works towards the base classes, the opposite of construction order.
Winterdyne Solutions Ltd is recruiting - this thread for details!
"delete this" is a scary beast of many possibilities for undefined behavior.

Parashift's C++ FAQ has an entire entry on it:

Quote:From [16.15] Is it legal (and moral) for a member function to say delete this?:

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

Here's how I define "careful":

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).
You must be absolutely 100% positive sure that your member function will be the last member function invoked on this object.
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).
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.


An additional tip:

Making all your constructors private: is likely a good idea.

Even when allocating with new, people will expect symetry and try to delete it directly. If your object is managing it's own deletion, this may incorrectly result in it's premature destruction (or if when releases occur is really obtuse, multiple deletion). For this to work, one must provide a stati function (or the like) which allocates the object on their behalf:

class foo {     foo( int i ) : refcount( 1 ) {}public:     static foo * create( int i ) { return new foo( i ); }     void release( void ) {         if (!--refcount) delete this;     }private:     unsigned refcount;};int main () {    foo * object = foo::create( 42 ); //OK    object->release(); //OK    foo local_object( 42 ); //illegal: ctor is private}foo global_object( 42 ); //illegal: ctor is privatefoo * direct_new_object = new foo( 42 ); //illegal: ctor is private


As an added bonus, this strategy allows you to change allocation functions at a later date without having to find direct-new()s peppered throughout your code

This topic is closed to new replies.

Advertisement