对scoped_ptr的弱引用?

时间:2011-07-28 07:32:47

标签: c++ structure weak-ptr scoped-ptr

一般来说,我都遵循Google风格指南,我觉得这与我看待事物的方式很吻合。我也几乎完全使用boost :: scoped_ptr,这样只有一个经理拥有特定对象的所有权。然后我传递了裸指针,这个想法是我的项目的结构使得所有对象的管理者在使用它们的对象被销毁后总是被销毁。

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Smart_Pointers

这一切都很棒,但是我被一个令人讨厌的小内存踩踏错误所困扰,其中所有者恰好在删除使用它的对象之前被删除了。

现在,在每个人都跳起来之前我觉得这个模式很傻,为什么我不使用shared_ptr?等等,考虑一下我不希望拥有未定义的所有者语义。尽管shared_ptr会捕获这种特殊情况,但它会向系统用户发送错误消息。它说,“我不知道谁拥有这个,它可能是你!”

什么会帮助我本来是一个指向范围指针的弱指针。实际上,一个带有弱引用列表的作用域指针,当作用域指针析构时它们被清空。这将允许单一所有权语义,但给使用对象一个机会来捕捉我遇到的问题。

因此,以scoped_ptr的额外'weak_refs'指针和weak_ptr中'next_weak_ptr'的额外指针为代价,它将成为一个整洁的小单一所有者,多个用户结构。

它甚至可能只是一个调试功能,所以在'release'中,整个系统只会转回一个正常大小的scoped_ptr和一个用于弱引用的标准单指针。

所以这......我的问题是:

  1. 我是否已经在stl / boost中有这样的指针/模式 失踪,或者我应该自己滚动?
  2. 有没有更好的方法呢? 仍然符合我的单一所有权目标?
  3. 干杯, 沙恩

4 个答案:

答案 0 :(得分:6)

  

2.是否有更好的方式,仍然符合我的单一所有权目标?

使用shared_ptr,但作为类成员使其成为该类的不变量的一部分,而公共接口只暴露了获取weak_ptr的方法。

当然,病态代码可以根据需要从shared_ptr保留自己的weak_ptr。我不建议在这里试图保护马基雅维利,只针对墨菲(使用萨特的话)。另一方面,如果您的用例是异步的,那么锁定weak_ptr返回shared_ptr这一事实可能是一个功能!

答案 1 :(得分:3)

  

尽管shared_ptr会捕获这种特殊情况,但它会向系统用户发送错误消息。它说,“我不知道谁拥有这个,它可能是你!”

shared_ptr并不意味着“我不知道谁拥有这个”。这意味着“我们拥有这个。”仅仅因为一个实体没有独占所有权并不意味着任何人都可以拥有它。

shared_ptr的目的是确保指针不会被销毁,直到共享它的每个人都同意它应该被销毁。

  

stl / boost中是否有这样的指针/模式,我错过了,或者我应该自己滚动?

您可以使用shared_ptr,就像使用scoped_ptr一样。仅仅因为它可以共享并不意味着你来分享它。这将是最简单的工作方式;只需将单一所有权作为约定而不是API建立的规则。

但是,如果你需要一个单一所有者且指针很弱的指针,那么Boost中就没有一个指针。

答案 2 :(得分:1)

我不确定弱指针会对此有多大帮助。通常,如果是 组件X使用另一个组件Y,X必须被告知Y的消亡, 不只是使指针无效,但可能是从列表中删除它, 或改变其运作方式,使其不再需要 宾语。许多年前,当我第一次开始使用C ++时,有一阵骚动 试图找到一个好的通用解决方案的活动。 (问题是 当时叫做关系管理。)据我所知,没有好处 每个发现的通用解决方案;至少,我参与的每个项目 使用了基于Observer模式的手工构建解决方案。

我的网站上确实有一个ManagedPtr,当它还在运行时,表现得很好 就像你描述的那样。在实践中,除了特定的 导致它的案例,我从来没有找到真正的用途,因为 总是需要通知。然而,实施起来并不难; 托管对象派生自ManagedObject类,并获取所有 指针(ManagedPtr,而不是原始指针)从它发出。 指针本身在ManagedObject类中注册,并且 ManagedObject类的析构函数访问它们,并“断开连接” 通过将实际指针设置为null来实现它们。当然,ManagedPtr 具有isValid函数,以便客户端代码可以在之前进行测试 解引用。这很好用(无论对象如何 托管 - 我的大多数实体对象“拥有”自己,然后做一个 delete this是对某些特定输入的回应),除了你倾向于 泄漏无效ManagedPtr(例如,每当客户端保留指针时) 在某种容器中,因为它可能有多个),和 如果客户需要采取某些措施,他们仍然不会得到通知 对象死亡。

答案 3 :(得分:0)

如果您恰好使用QT,QPointer基本上是指向QObject的弱指针。它将自身连接到指向值中的“我刚被破坏”事件,并根据需要自动使其自身无效。不过,如果你还没有跳过QT的箍,这是一个非常重要的库,可以用来进行错误跟踪。

相关问题