我可以使用要删除的对象的回调删除另一个拥有的对象吗?

时间:2011-06-29 21:08:36

标签: c++ object delete-operator

我有一个类(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(以及我上面的代码)是“危险的”,有没有更安全的方法来解决我的问题?

2 个答案:

答案 0 :(得分:5)

这实际上与在delete this;中调用willDeleteYourself一样好。如果您在删除后没有访问任何成员,则可以。

答案 1 :(得分:4)

  

对象无法直接删除

对象不能delete本身没有特别的原因,在删除对象后必须小心不要访问任何成员,但有些情况下它是有意义的。

我已经完成了一些封装线程或计时器的“即发即弃”对象。它们并非由任何其他对象拥有,因此它们可能会动态创建并泄露直到完成其工作。然后他们会将delete this;称为最后一次操作。

需要(或想要)删除对象的位置添加中间步骤,删除代码本身只会使事情变得更复杂,更难维护。以下代码:

void willDeleteOurself() {
   delete this;
   // [1]
}

更明确,更容易理解:从这一点开始,对象已经死了,你不能使用它,不要在[1]中添加代码,因为对象已经死了现在。另一方面,如果您通过回调伪装delete,那么其他人可能会看到代码并且没有意识到向[1]添加代码是危险的。