7

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

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

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

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

解决方案是什么?

4

6 回答 6

10

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

于 2010-04-22T02:28:10.023 回答
3

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

于 2010-04-22T03:20:26.707 回答
1

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

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

于 2010-04-22T02:45:08.347 回答
0

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

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

我认为它完全使共享指针的目的无效。

最好的解决方案是修复库。

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

于 2010-04-22T03:10:06.290 回答
0

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

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

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

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

于 2010-04-22T03:22:27.307 回答
0

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

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

需要注意的事项:

  1. 所有对象都必须通过 new 分配对象析构函数才能正确释放它们。
  2. 如果您忘记为对象设置父对象,它将泄漏
  3. 处理不从 Object 继承的对象很棘手,尽管可以通过定义一个从 Object 继承的模板类来保存它们。
于 2010-04-22T03:27:42.093 回答