【问题标题】:Can I delete an object owned by another with a callback from the object to be deleted?我可以使用要删除的对象的回调来删除另一个拥有的对象吗?
【发布时间】:2011-06-29 21:08:35
【问题描述】:

我有一个班级 (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() 的末尾,但调用该方法的对象已被销毁。

当我在调用 owner->deleteObject(); 之后没有更多引用 obj 的语句时,此构造是否安全?

更新

感谢您的回答。我在这里简化了一点。我没有A* obj;,而是一个指向对象的提升智能指针(单独,有时在地图中)。我想如果我在包装对象上调用delete this,智能指针将无法识别底层对象已被删除。对吗?

由于delete this(以及我上面的代码)是“危险的”,有没有更安全的方法来解决我的问题?

【问题讨论】:

    标签: c++ object delete-operator


    【解决方案1】:

    这实际上和在willDeleteYourself 中调用delete this; 一样好。删除后不访问任何成员即可。

    【讨论】:

      【解决方案2】:

      对象不能直接删除自己

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

      我已经通过一些封装线程或计时器的即发即弃对象来做到这一点。它们并不真正拥有任何其他对象,因此它们可能会被动态创建并泄露直到它们完成它们的工作。然后他们会调用delete this; 作为最后的操作。

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

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

      更加明确且易于阅读:从这一点开始,对象已死,您无法使用它,请勿在 [1] 中添加代码,因为对象已死现在。另一方面,如果您通过回调伪装delete,那么其他人可能会看到代码而没有意识到将代码添加到[1]是危险的。

      【讨论】:

      • 是的,你是对的,直接delete this 更清楚。但正如我在问题中添加的那样,我认为这不适用于智能指针......
      • 这里的问题是你有一个问题,但你问的是完全不同的事情,如果资源的管理在其他地方处理,那么它必须在它被释放的地方,否则你最终会搞乱资源的管理。现在,根据操作的具体情况,我已经看到它通过函数的返回值进行处理,因此对象可以向调用者发出 我从现在开始无用的信号,这可以在释放资源。
      猜你喜欢
      • 2019-12-14
      • 2020-10-30
      • 1970-01-01
      • 1970-01-01
      • 2013-07-16
      • 2014-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多