【问题标题】:How to prevent anyone from stealing my shared_ptr?如何防止任何人窃取我的 shared_ptr?
【发布时间】:2011-02-10 21:13:58
【问题描述】:

因此,我将 boost::shared_ptr 用于它提供的所有各种引用计数优势——显然,对于初学者的引用计数,以及复制、分配和存储在 STL 容器中的能力。

问题是,如果我只将它传递给一个“恶意”函数或对象,则该对象可以保存 ptr,然后如果外部函数或对象很好地放弃其所有权,我将永远无法解除分配它.

最终,我尝试保持明确的对象所有权。我通过让所有者将唯一的 shared_ptr 保留给对象来实现这一点,而“guest”对象只将 weak_ptr 存储到对象中。

我真的不想要 shared_ptr 的“共享”部分,但我需要使用 shared_ptr 来制作weak_ptr。我想使用 scoped_ptr,但它非常有限,因为你不能复制它。您不能将其存储在容器中,不能从中借出weak_ptrs,也不能将所有权转让给新的经理。

解决办法是什么?

【问题讨论】:

  • 这就是分享的问题,不是吗:(
  • 请注意,任何拥有weak_ptr 的人都可以lock() 它。因此,即使您从未授予他们所有权,他们也可以随时尝试窃取它。

标签: c++ boost shared-ptr ownership


【解决方案1】:

将其设为私有并提供外观来执行所需的任何操作。没有人看到指针。我想那时你甚至不需要 shared_ptr。

【讨论】:

  • +1 表示私有,虽然shared_ptr 的明显好处是能够获取weak_ptr,这使用户可以知道原始对象是否仍然存在。
【解决方案2】:

正如您在问题中描述的那样,将weak_ptr 用于来宾对象就足够了。否则你会遇到死指针的问题。

我会考虑进行应用程序重构以删除“恶意”函数/对象或至少修复它们的行为。

【讨论】:

  • 事实证明,我控制了所有代码,因此我自己删除了“恶意”(或者我应该说“天真”)代码。我将继续使用 shared_ptrs 并且尽可能地使用 weak_ptr 更加小心,因为我确实需要 expired() 检查。我真的很讨厌这样做,因为我经常觉得自己是自己最大的敌人,因为当我打算保存一个weak_ptr时,我总是不小心保存了shared_ptrs。总的来说,这似乎是 shared_ptrs 的一个大问题,因为它们通常比你想要的更粘。
  • 接受这个答案,因为这是我个人最终要做的,但它不会帮助任何对代码控制有限的人。感谢大家发布他们的解决方案,他们对我来说都很好。我希望 boost 会出现 'owned_ptr' 之类的......
【解决方案3】:

您可以扩展 shared_ptr boost 类并覆盖 delete 以强制删除指针。

真正的问题是,如果库没有释放或释放 shared_ptr,那么它可能会在一段时间内引用它。此时,您的应用程序将使用 SIGSEGV。

我认为这完全违背了共享指针的目的。

最佳解决方案是修复库。

其他解决方案,使用 AOP 在您正在调用的库函数退出时删除指针。这仍然有可能打破。

【讨论】:

    【解决方案4】:

    不要传递 boost::shared_ptr 对象...即使您在内部使用 boost::shared_ptr 存储该对象,您也应该确保函数通过常量引用而不是副本来获取您的对象共享指针。由于您需要取消引用共享指针才能将对象传递给通过 const 引用传递的函数,因此您将知道它是否遵循该协议。

    【讨论】:

    • 通过指针或引用传递对象的一些经验法则:a) 仅当您想转移所有权时才通过普通/自动指针传递(基本上仅限 shared_ptr 构造函数) b) 如果被调用者必须无论如何保留访问权,通过 shared_ptr CONST 引用或值传递(通过 shared_ptr 非常量引用传递具有非常模糊的语义,如果您开始考虑它 - 仅在真正需要时使用它)。您可以通过将 shared_ptr 转换为 const 来确保调用方的这一点。 c) 在所有其他情况下,通过 (const) 引用传递给对象。你也可以在打电话时保证这一点。
    【解决方案5】:

    对于您所描述的内容,确实没有好的解决方案。

    您不能使用 auto_ptr,因为您没有转移所有权。

    如果您可以保证所有者比引用更长寿,我建议在所有者中使用 scoped_ptr/store by value,然后将原始指针或引用传递给需要它的人。

    如果引用可以比所有者更长寿(并且需要优雅地通知引用),则必须使用 shared_ptr/weak_ptr。但是,正如您所说,您不能阻止任何类/函数锁定 weak_ptr 和“防止”释放。但是,在接口中,不要传递shared_ptr,传递weak_ptr。它只是与约定一样强大,但它说“不要坚持这个,它可能会消失”。

    【讨论】:

      【解决方案6】:

      如果您想在该所有者/拥有的范例中处理您的对象,我建议您执行 Qt 之类的操作。

      1. 创建一个基类 Object,系统中的所有类都将从该基类继承。每个对象都跟踪其父/所有者和子对象。
      2. 使用setOwner(Object * owner) 方法设置所有者并让该方法确保通知所有者对象有关新子对象的信息。
      3. Object 的析构函数在销毁时应删除所有子对象。
      4. 定义一个模板类,它定义了一个指向 Object 子类的智能指针。使对象通知任何连接的智能指针有关其销毁的信息,以便在对象被销毁时值将变为 NULL。

      注意事项:

      1. 必须通过 new 分配所有对象,对象析构函数才能正确释放它们。
      2. 如果您忘记为对象设置父对象,它会泄漏
      3. 处理不继承自 Object 的对象很棘手,但可以通过定义一个继承自 Object 的模板类来保存它们。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-18
        • 2011-05-09
        • 2010-10-28
        • 2013-05-25
        • 1970-01-01
        • 1970-01-01
        • 2010-09-15
        • 2011-11-04
        相关资源
        最近更新 更多