In my initial basic tests it is perfectly safe to do so. However, it has struck me that attempting to manipulate this
later in a function that delete
s this
could be a runtime error. Is this true, and is it normally safe to delete this
? or are there only certain cases wherein it is safe?
delete this
is legal and does what you would expect: it calls your class's destructor and free the underlying memory. After delete this
returns, your this
pointer value does not change, so it is now a dangling pointer that should not be dereferenced. That includes implicit dereferencing using the class's member variables.
It is usually found in reference-counted classes that, when the ref-count is decremented to 0, the DecrementRefCount()
/Release()
/whatever member function calls delete this
.
delete this
is typically considered very bad form for many reasons. It is easy to accidentally access member variables after delete this
. Caller code might not realize your object has self-destructed.
Also, delete this
is a "code smell" that your code might not have a symmetric strategy for object ownership (who allocates and who deletes). An object could not have allocated itself with new
, so calling delete this
means that class A is allocating an object, but class B is later freeing it[self].
delete this
in a destructor. –
Saunders It's safe to delete "this" as long as it's essentially the last operation in the method. In fact several professional level APIs do so (see ATL's CComObject implementation for an example).
The only danger is attempting to access any other member data after calling "delete this". This is certainly unsafe.
delete this
in a destructor –
Saunders Delete this is perfectly legal as others have already mentioned. It is risky for one additional reason that hasn't been mentioned yet - you are assuming that the object has been allocated on the heap. This can be difficult to guarantee, although in the case of reference counting implementations isn't generally a problem.
delete this
s itself. –
Angara but dont do it in the destructor !
As stated by others, delete this is a valid idiom but for it to be safe you have to ensure that the object is never instantiated on the stack.
One way to do this is to make both the constructor and the destructor private and enforce object creation through a class factory function which creates the the object on the heap and returns a pointer to it. The class factory can be a static member function or a friend function. Cleanup can then be done through a Delete() method on the object that does the "delete this". COM objects basically work this way except that in addition they are reference counted with the "delete this" occurring when the reference count is decremented to zero.
Yes. It should be perfectly fine. "This" is just a pointer. Any pointer will do for delete. The information on how to delete an object is contained in the heap records. This is how IUnknown::Release() is usually implemented in COM objects.
delete this can cause an issue when you have subclasses of the object you are deleting. Remember construction starts from top down and deletion starts from bottom up. So if delete this is in the middle of the hierarchy you basically lost all the objects below this particular class.
delete this comes very handy when you are implementing a reference counted object, an example of which is the COM classes.
Read for a similiar discussion. Your understanding is right in that it does work, is needed, and can be dangerous since you can't access this afterwards.
If you are inheriting from a base class and gave delete this in the base class function, using derived class pointer will cause a crash. E.g:
class Base
{
virtual void Release()
{
delete this;
}
}
class Derived : public Base
{
void Foo()
{
...
}
}
main()
{
Base *ptrDerived = new Derived();
ptrDerived->release();
ptrDerived->Foo() //Crash
}
delete this
at all. Did you somehow expect that the Derived
part of the object would remain alive? Then you don't know anything about C++ object lifetime. Also, which is it: Release()
or release()
? –
Biology © 2022 - 2024 — McMap. All rights reserved.