Should "delete this" be called from within a member method?
Asked Answered
C

12

20

I was just reading this article and wanted SO folks advice:

Q: Should delete this; be called from within a member method?

Centaury answered 7/12, 2009 at 18:23 Comment(8)
An even better question "Should you ever use 'delete this'"? Answer - no.Sophistic
There are rare occasions when it's appropriate to call "delete this" - but they are very rare...Register
@Neil: You can't use delete this anywhere other than a member function (or an initializer in a constructor, I guess, but that just hurts my brains). So you should totally post that as an answer.Gereron
what will happen if you delete this; inside destructor? :)Bacchant
@Steve, if I post it as an answer, it will immediately get a deluge of downvotes from COM fans!Sophistic
My argument against it. Is that there is no way for the object to know if it was dynamically allocated. Thus there is no way to make sure at the compiler level that the delete is valid.Sievers
@Martin York: With a static factory-method and a private constructor, you can guarantee that an object was dynamically/heap allocated.Theresita
related: #2072079Centaury
G
33

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;
  }
}
Gardia answered 7/12, 2009 at 18:26 Comment(1)
You just spelled it fine, Elcuco. What's your point? Are you afraid that an object destroying itself would create more dangling pointers than there'd be if something else destroyed the object instead? foo->Deref() is no worse than if (foo->Deref() == 0) delete foo;. Besides, if the reference count is zero, then there aren't any other pointers to be left dangling anyway.Sitsang
F
12

I think there are really 2 questions here

Can delete this be validly called from a member method?

Yes. This is legal as long as you are very careful with the usage.

Should delete this be used within a member method?

In very specific cases this is necessary. Certain types of smart pointers for instance use the delete this pattern to kill the pointer. Examples: CComPtr<> style.

Other than smart pointers though, it should be avoided unless you have a very good reason for doing this. Even then, I would carefully reconsider my scenario and see if there was a way around it.

Fantastically answered 7/12, 2009 at 18:27 Comment(0)
O
11

Yes you can and here's a good explanation of when and why

Outshoot answered 7/12, 2009 at 18:29 Comment(1)
Or here is a link that explains the danger and reading between the lines of why you should not do it.Sievers
N
5

Yes, there are a few cases where it is common.

Reference counting:

void release() 
{
  cnt--;
  if (cnt == 0) 
    delete this;
}

GUI programming. In some frameworks, when a user closes a window it is common for the window to delete itself.

Nudd answered 7/12, 2009 at 18:28 Comment(0)
S
5

Getting ready for the down votes.

Should it: No.
Can it Technically: Yes
Is it a good idea: Absolutely not.
Are there situation it is useful: Of course. If you are C++ foo is exceedingly strong. But most people are not that good. So only do this if you have a team of people working with you able to do decent code review.

Why:
There is no way for an object to know that it has been dynamically allocated (and thus needs deleting) or is a normal object (and thus must not be deleted) and thus how can it decidide weather it should be deleted. Thus if an object is deleting itself then in my opinion there is somthing terribly wrong with the design.

If you have an object that needs managing then you should write a seprate object to do the management (hence smart pointers). Let the object do what it is good at, then seporate the management of the object into another object.

Sievers answered 7/12, 2009 at 19:19 Comment(2)
Also note that "outside of the class" you still cannot be sure that a pointer really points to dynamically allocated object and not a automatic or static object for example. (In fact I think that in many cases you can be even less sure then in member function...) So delete p is risky regardless of whether p is this or not.Architectural
@Adam: Thanks. But as pointed out it 'can' be useful. But in modern C++ it is considered better practice to separate management of the object from the implementation of the object (Hence smart pointers are now used rather than COM). Also note a management object can easily grantee that the object it manages is dynamically allocated so that is completely a false premise.Sievers
R
1

Not without a very good reason to do so.

The problem is that when you call delete this in a member function, you're creating a nasty side effect - the caller still has a reference to your instance that is now completely invalid.

This is probably not an expected behavior, so it could easily lead to nasty bugs.

That being said, there are times when this is appropriate (I've seen some memory management schemes, with certain libraries, where you explicitly create methods in the classes that delete themselves - primarily for language interoperability). In general, I think it's bad practice, though.

Register answered 7/12, 2009 at 18:26 Comment(0)
D
1

Some threading libraries use it when implementing an auto destroy on thread termination.

void Thread::threadFunc()
{
    doRun();

    if(this->destroyOnExit == true)
        delete this;
}
Defy answered 7/12, 2009 at 18:51 Comment(0)
L
1

This was often used in the MFC days. IIRC the last message a window receives is WM_NCDESTROY, at which point you could call delete this, assuming you were some form of sadist of course (although MFC itself did this at times I think.)

Larocca answered 7/12, 2009 at 19:10 Comment(1)
Yes, MFC OnDestroy() function does that :)Mozambique
B
0

You can do it, provided its the last element in a member function, and that after return you forget that object ever existed.... but yeah, like that article asks ... Why would you want to do this ? I don't know what the standard says, but it does give me a funny feeling :P

I guess this is a bit like should you ever use a GOTO statement, and I personally use GOTO to clean up resources in C sometimes, especially under exceptional conditions.

I wonder what the shared state implications are (fuzzy statement I know):P

Bubbler answered 7/12, 2009 at 18:29 Comment(0)
C
0

Yes. Like all the answers say, if you're 100% sure that the class's data will not be used after the delete this is called.

For example, in one project:

void Test()
MyClass * Someclass = new MyClass;
SomeClass->DoYourThing();
SomeClass->KillYourself();
return;

void MyClass::DoYourThing() { return; }
void MyClass::KillYourself() {delete this;}

Very simplistic explanation, the project used delete this; as part of the memory management for objects of that type; their constructor added them to a private list of classes of that type in use, and removed themselves from that list when they were destroyed and then deleted themselves (this was not in a destructor). Any objects of that class that hadn't deleted themselves when the program reached its endpoint then all had their KillYourself() equivalent called from a static member function CleanYourselves()

Crowfoot answered 7/12, 2009 at 19:28 Comment(0)
S
0
  1. delete this can not be called from a non member function :)
  2. It is a bad idea to do until you understand it's consequences.
Subrogation answered 8/12, 2009 at 16:18 Comment(0)
B
0

Although not directly related to this thread i wanted to clarify this. I was asked a question that given a situation:

int* a = new int ;
int* b = a ;
delete a;

Now is the next statement safe?

cout<<*b ;

My answer: After delete a, the location pointed to by a has been marked for deletion and at any point of time it can be assigned to some other object. Hence accessing the value using b is not safe as it may get modified after being allocated to some other object.

Note: No downvoting please, this is just a clarification

Basketwork answered 30/12, 2009 at 12:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.