我有一个类(A
)知道什么时候应该删除它。我相信一个对象不能直接删除自己(即,你不能从里面调用析构函数)所以我使用了一个回调。
以下是我当前解决方案的伪代码:
class A {
Owner* owner; // is set in constructor
A(Owner* ow) : owner(ow) {}
void willDeleteOurself() {
owner->deleteObject();
}
}
class Owner {
A* obj;
Owner() { // e.g. constructor
obj = new A(this);
}
void deleteObject() {
delete obj;
}
}
我有一个类Owner
的对象,它拥有类A
的对象。现在,在某些时候,obj
“知道”它应该被删除,并且会发生willDeleteOurself()
的调用。这段代码似乎有效。
现在,我的问题是:这是一种安全的删除方式吗 obj
?
我担心因为当方法deleteObject
返回(到达}
)时,它会跳回到willDeleteOurself()
的末尾,但是该方法被调用的对象已经被破坏。
在调用obj
之后我没有更多引用owner->deleteObject();
的语句时,这个构造是否安全?
更新:
感谢您的回答。我在这里简化了一下。我没有A* obj;
,而是对象提升smartpointer(单独,有时在地图中)。我想如果我在包装对象上调用delete this
,智能指针将无法识别基础对象被删除。这是对的吗?
由于delete this
(以及我上面的代码)是“危险的”,有没有更安全的方法来解决我的问题?
答案 0 :(得分:5)
这实际上与在delete this;
中调用willDeleteYourself
一样好。如果您在删除后没有访问任何成员,则可以。
答案 1 :(得分:4)
对象无法直接删除
对象不能delete
本身没有特别的原因,在删除对象后必须小心不要访问任何成员,但有些情况下它是有意义的。
我已经完成了一些封装线程或计时器的“即发即弃”对象。它们并非由任何其他对象拥有,因此它们可能会动态创建并泄露直到完成其工作。然后他们会将delete this;
称为最后一次操作。
从需要(或想要)删除对象的位置添加中间步骤,删除代码本身只会使事情变得更复杂,更难维护。以下代码:
void willDeleteOurself() {
delete this;
// [1]
}
更明确,更容易理解:从这一点开始,对象已经死了,你不能使用它,不要在[1]中添加代码,因为对象已经死了现在。另一方面,如果您通过回调伪装delete
,那么其他人可能会看到代码并且没有意识到向[1]添加代码是危险的。