Reputation: 6790
I have a class that employs a reference counting mechanism. The objects of this class are eventually destroyed by calling delete this
when the reference count drops to zero. My question is: can I use local on-stack variable after delete this
? Here's a more specific example:
class RefCountedClass
{
public:
RefCountedClass(Mutex& m) :
mutex_(m)
{}
.
.
.
private:
Mutex& mutex_;
void RemoveReference()
{
// As I understand, mutex_ will be destroyed after delete,
// but using m is all right because it is on-stack and
// references an external object. Am I right?
Mutex& m = mutex_;
m.Acquire();
--recount_;
if (refcount <= 0) delete this;
m.Release();
}
};
Upvotes: 7
Views: 639
Reputation: 545686
Yes, you may do this, as long as the member variable itself is really only a reference to an external object.
(Please forgive the previous wrong answer, I was confused about the mutex_
variable.)
Upvotes: 7
Reputation: 3166
Yes, you can, but why not to use atomic decrement instead of decrementing the counter under the mutex? And do you actually need to protect (by mutex) object destruction? Indeed, after counter becames 0 the only current thread can acess the object.
So, maybe it is possible to rewrite your code as
int tmp_count; m.Acquire(); tmp_count= --recount_; m.Release(); if (tmp_count <= 0) delete this;
(or use atomics to decrement and test the counter)
Upvotes: 1
Reputation: 28892
Generally the only thing you are not allowed to call after delete this
is anything that makes a reference to this
. This include any non-static class member or function.
In your case, there is a good chance that RemoveReference
will not work. This is becuase m
points to mutex_
which no longer exists after delete this. Your best bet could well be making mutex_
static.
Edit: Although mutex_
points to an external variable which continues to exist after the class is deleted, there is no bulletproof guarantee that the compiler will not refer back to mutex_
after the class is deleted to obtain the value of the external mutex. There is a good chance that things will work as expected but I do not believe this can be guaranteed.
Upvotes: 0
Reputation: 2984
Yes in this case. Your stack variable 'm' points to an external resource that you get in the constructor
Upvotes: 0