我有一个使用引用计数机制的类。当引用计数降至零时,最终通过调用delete this
来销毁此类的对象。我的问题是:我可以在delete this
之后使用本地堆栈变量吗?这是一个更具体的例子:
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();
}
};
答案 0 :(得分:7)
是,you may do this,只要成员变量本身实际上只是对外部对象的引用。
(请原谅以前的错误答案,我对mutex_
变量感到困惑。)
答案 1 :(得分:1)
是的,你可以,但为什么不使用原子减量而不是减少互斥量下的计数器呢?你真的需要保护(通过互斥)对象破坏吗?实际上,在计数器为0之后,唯一的当前线程可以访问该对象。
所以,也许可以将代码重写为
int tmp_count; m.Acquire(); tmp_count= --recount_; m.Release(); if (tmp_count <= 0) delete this;
(或使用原子来递减和测试计数器)
答案 2 :(得分:0)
通常情况下,delete this
之后唯一不允许调用的内容是引用this
的任何内容。这包括任何非静态类成员或函数。
在您的情况下,RemoveReference
很可能无效。这是m
指向mutex_
指向删除后不再存在的mutex_
。您最好的选择可能是mutex_
静态。
编辑虽然mutex_
指向在删除类后继续存在的外部变量,但没有防弹保证编译器不会引用回{{1}删除类后,获取外部互斥锁的值。事情很有可能按预期发挥作用,但我不相信这可以得到保证。
答案 3 :(得分:0)
在这种情况下是的。堆栈变量“m”指向您在构造函数中获得的外部资源