2010-04-22 59 views
7

因此,我使用boost :: shared_ptr来提供它提供的各种引用计数优点 - 显然对初学者有引用计数,但也有复制,分配和存储在STL Containers中的能力。如何防止任何人窃取我的shared_ptr?

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

最终,我尽量保持对象所有权的明确。我通过让所有者将唯一的shared_ptr保存到对象来实现这一点,而“guest”对象仅将weak_ptrs存储到对象。

我真的不想shared_ptr的“共享”部分,但我需要使用shared_ptr来使weak_ptrs。我想使用scoped_ptr,但由于无法复制,所以它非常有限。您不能将其存储在容器中,不能将weak_ptrs借出,并且无法将所有权转让给新的经理。

解决方案是什么?

+0

这就是分享的问题,是不是:( – Cascabel 2010-04-22 06:03:00

+0

请注意,任何有'weak_ptr'的人都可以'锁定'它,所以他们总是可以试图窃取它,即使你永远不会给他们所有权 – MSalters 2010-04-22 08:53:40

回答

1

正如您在讨论中所描述的那样,对访客对象使用weak_ptr已经足够了。否则,你会遇到死指针的问题。

我会考虑做应用程序rearchitect删除“恶意”功能/对象或至少修复其行为。

+0

事实证明,我控制所有的代码,所以我最终删除了“恶意”(或者我应该说“天真”)自己的代码。我将继续使用shared_ptrs,并且只要我可以使用weak_ptr就会更加小心,因为我确实需要过期()检查我真的很讨厌这样做,因为我经常感觉自己是我自己最大的敌人,因为当我打算s时意外保存shared_ptrs ave a weak_ptr。一般来说,这似乎是shared_ptrs的一个大问题,因为它们通常比你想要的更粘。 – Kyle 2010-04-23 00:23:12

+0

接受这个答案是因为这是我亲自完成的工作,但它无法帮助控制代码的任何人。感谢大家发布他们的解决方案,他们都对我很好。我希望boost会出现'own_ptr'或其他东西... – Kyle 2010-04-26 15:26:57

10

让它变得私密,并提供一个外观来做任何需要的操作。没有人看到指针。我想那时你甚至不需要shared_ptr。

+0

+1为private,虽然这里'shared_ptr'的明显好处是能够获得'weak_ptr',这允许用户知道原始对象是否仍然存在。 – 2010-04-22 06:18:18

0

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

问题的确是,如果库没有释放或释放shared_ptr,那么它可能会引用它一段时间。在这个时候你的应用程序将落入SIGSEGV。

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

最佳解决方案是修复库。

其他解决方法,使用AOP删除指定库函数退出时指针。这仍然可能会打破。

4

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

+1

通过指针或引用传递对象的几条经验法则: a)仅当您想传输所有权时才传递纯指针/自动指针(基本上是shared_ptr构造函数只有) b)如果被调用者必须保留访问权限,不管怎样,通过shared_ptr CONST引用或值(通过shared_ptr传递非const引用具有非常模糊的语义,如果你开始考虑它 - 只有当真正使用它时需要)。你可以通过将你的shared_ptr强制转换为const来保证在调用者方面。 c)在所有其他情况下,将(const)引用传递给对象。您也可以在打电话时保证这一点。 – 2010-04-22 08:59:02

0

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

由于您未转让所有权,您无法使用auto_ptr。

如果您可以保证拥有者超过了引用,我建议在所有者中使用scoped_ptr/store的值,然后将原始指针或引用传递给需要它的人。

如果引用超出所有者(并且引用需要得到适当的通知),则必须使用shared_ptr/weak_ptr。但是,正如你所说的,你不能阻止任何类/函数锁定weak_ptr和“防止”重新分配。但是,在接口中,不要传递shared_ptr,传递weak_ptr。它只是像一个惯例一样强大,但它说“不要拘泥于此,它可能会消失”。

0

如果你想处理你拥有的所有者/拥有范例中的对象,我建议你做一些类似Qt的事情。

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

事情需要提防:

  1. 所有对象都必须通过新的对象被分配析构函数正确地取消分配它们。
  2. 如果您忘记设置对象的父级,它会泄漏
  3. 处理不从Object继承的对象是棘手的,尽管可以通过定义一个继承自Object的模板类来保存他们。
相关问题