【问题标题】:Detecting if an object is still active or it has been destroyed检测对象是否仍处于活动状态或已被破坏
【发布时间】:2015-09-08 01:01:06
【问题描述】:

假设我有一堂课:

class Foo {
 public:
    int a;
}

该类通过new 运算符实例化,并由Bar 类的对象B 通过delete 运算符销毁。

如果是 Bar 类的对象 B,则实例化 Foo 类的新对象 A,然后将对象 A 的指针传递给 Baz 类的 C 对象。如果 Bar 类的对象 B 已被自我删除,那么 Baz 类的对象 C 如何检测对象 A 是否处于活动状态或已被删除。注意:这是在一个非常小的嵌入式系统上,因此不能使用任何库,甚至不能使用 std。请参见下面的序列图。

|------|                               |------|
| B:Bar|                               | C:Buz|
|------|                               |------|
   ||          |-------|                  ||
   ||---New--->| A:Foo |                  ||
   ||          |-------|                  ||
   ||             ||                      ||
   ||             ||                      ||
   ||-----C:Buz.set_foo_Ptr(&A:Foo);----->||
   ||             ||                      ||
   ||---Delete--->X                       ||
   ||                                     ||
   X  (B:Bar Self Deleted)                ||
                                          ||
                          (Can C:Buz know if A:Foo
                          has been deleted or not ?)

【问题讨论】:

  • 似乎是std::weak_ptr的好人选
  • 我不知道标准是否说明了这种用法,但动态演员表会起作用(并且可靠)吗?
  • 你需要它被删除吗?还是删除可能没问题?
  • 您的问题是您正在创建和分发指针,但没有一个实体负责销毁它们。这就是我们有 std::shared_ptr 和 std::weak_ptr 的原因。
  • 这个Q有点像stackoverflow.com/questions/677653/…...,希望对你有帮助

标签: c++


【解决方案1】:

您在这里遇到了所有权问题。通常,您会使用 stl 智能指针之一来处理此问题,但正如您所说,没有 stl...您将不得不非常仔细和明确地管理指针的所有权。

在没有封闭对象的情况下传递指向 A 的指针是一个坏主意。现在你 C 拥有 A 但 B 也拥有 A。这不好。要么将 B 传递给 C,让 C 通过 B 访问 A,要么提供访问器函数。或者将 A 传递给 C 并确保 C 是唯一管理 A 的对象(即 C 无论如何都会删除所有 A 对象)。

我想如果你必须的话,你可以在 B 中包含一个标志来确定谁拥有 A 的所有权 - 默认情况下它设置为“B”,但一旦通过它就可以设置为“C”,并且在以下情况下使用B被删除是为了告诉B是否删除A。

【讨论】:

    【解决方案2】:

    嗯,根据定义,你不能,因为已经销毁的对象不再存在。而且你不能检查不存在的东西......

    一个更实用的方法是已经指出的weak_ptr,或者一个signal&slot组合来通知感兴趣的对象A的破坏。

    【讨论】:

    • 谢谢,我就是这么想的,但想得到更多的意见。我在问一个后续问题:stackoverflow.com/questions/677653/….
    • 所以在问了第二个问题之后,@gbjbaanb 正在引导我朝着更好的方向前进,所以我要把他标记为答案,给你投赞成票,谢谢...
    • 没问题;有时会为您的问题提供更好的解决方案。 Stackoverflow 不是预言机,尽管它非常非常接近 :)
    【解决方案3】:

    您可以使用 B 的析构函数调用C:Buz.set_foo_Ptr(nullptr);,然后 C 可以在使用前测试 nullptr。

    【讨论】:

      【解决方案4】:

      两种选择:

      • 如果您只需要知道,请使用 std::atomic<bool> 变量来说明对象是否仍然存在
      • 相反,如果 onject C 仍需要访问对象,请使用智能指针。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-26
        • 2011-05-02
        • 1970-01-01
        • 2018-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-25
        相关资源
        最近更新 更多