views:

187

answers:

6
+3  Q: 

C++: Delete this?

Hi,

Is it allowed to delete this; if it the delete-statement the last statement that will be executed in that instance of the class? Or is it maybe allowed to delete that instance in a method called at the last statement in that class? Something like:

void doStuff()
{
     //blah blah, stuff, you know...
     delete changeModule(new MathModule()); // invented something...
     // changeModule returns the current module, which is 'this' module
}

or maybe:

void doStuff()
{
    otherClass.deleteMe(this); // void deleteMe(void *obj) { delete obj; }
}

Of course I'm sure that this class-instance is new-created.

If all this is allowed, is following allowed?

void doStuff()
{
    if (expression)
    {
        delete this;
        return;
    } else
    {
         // Do something else
    }
    // Do some other things...
}

Thanks

+15  A: 

The C++ FAQ Lite has a entry specifically for 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).

JaredPar
The corresponding FQA also has some useful comment : http://yosefk.com/c++fqa/heap.html#fqa-16.15
Alexandre C.
@Alexandre: How does it qualify as useful? About all I can see it showing is that the author understands neither C++, nor non-trivial programming in general.
Jerry Coffin
tone is deliberately harsh. The author does understand C++, but please read the FQA with a critical eye. The advice on declaring the destructor private and using a static factory function is useful.
Alexandre C.
@Alexandre: I've read it several times -- at least if he believes most of what he says, he clearly understands neither C++ nor programming in general. This is a prime example -- he talks about syntax, but `delete this;` is about semantics, and specifically an object that knows its own lifetime.
Jerry Coffin
+2  A: 

Yes, delete this; has defined results, as long as (as you've noted) you assure the object was allocated dynamically, and (of course) never attempt to use the object after it's destroyed.

Some consider this a nasty hack, and tell anybody who will listen that it should be avoided. One commonly cited problem is the difficulty of ensuring that objects of the class are only ever allocated dynamically. Others consider it a perfectly reasonable idiom, and use it all the time. Personally, I'm somewhere in the middle: I rarely use it, but don't hesitate to do so when it seems to be the right tool for the job.

Edit: [mostly in response to @Alexandre C's comment]: the primary time you do this is with an object that has a life that's almost entirely its own. One example James Kanze has cited was a billing/tracking system he worked on for a phone company. Basically, when you pick up the phone, something takes note of that and creates a phone_call object. From that point onward, the phone_call object handles the details of the phone call (making a connection when you dial, adding an entry to the database to say when the call started, possibly connect more people if you do a conference call, etc.) When you hang up, the phone_call object does its final book-keeping (e.g., adds an entry to the database to say when you hung up, so they can compute how long your call was) and then destroys itself. The lifetime of the phone_call object is based on when you pick up/hang up the phone -- from the viewpoint of the rest of the system, it's basically entirely arbitrary, so you can't tie it to any lexical scope in the code, or anything on that order.

For anybody who might care about how dependable this kind of coding can be: if you make a phone call to, from, or through almost any part of Europe, there's a pretty good chance that it's being handled (at least in part) by code that does exactly this.

Jerry Coffin
Thanks, I'll put it somewhere in my memory. I suppose you define the constructors and destructors as private and use some static factory method to create such objects.
Alexandre C.
@Alexandre: You'd probably do that in most cases anyway -- I don't know anywhere close to all the details of the system he was working on, so I can't say for sure about it though.
Jerry Coffin
A: 

If it scares you, there's a perfectly legal hack:

void myclass::delete_me()
{
    std::auto_ptr bye_bye(this);
}

I think delete this is idiomatic C++ though, and I only present this as a curiousity.

Mark Ransom
A: 

You can do so. However, you can't assign to this. Thus the reason you state for doing this, "I want to change the view," seems very questionable. The better method, in my opinion, would be for the object that holds the view to replace that view.

Of course, you're using RAII objects and so you don't actually need to call delete at all...right?

Noah Roberts
A: 

It is allowed (just do not use the object after that), but I wouldn't write such code on practice. I think that delete this should appear only in functions that called release or Release and looks like: void release() { ref--; if (ref<1) delete this; }.

Kirill V. Lyadvinsky
A: 

Well, in Component Object Model (COM) delete this construction can be a part of Release method that is called whenever you want to release aquisited object:

void IMyInterface::Release()
{
    --instanceCount;
    if(instanceCount == 0)
        delete this;
}
UnknownGosu