【问题标题】:intrusive_ptr in c++11c++11 中的 intrusive_ptr
【发布时间】:2012-12-04 10:31:06
【问题描述】:

C++11 是否有与boost::intrusive_ptr 等价的东西?

我的问题是我的 C++ 代码有一个 C 风格的界面。接口的两端都可以使用 C++,但出于兼容性原因,需要公开 C 接口。我不能使用std::shared_ptr,因为我必须通过两个(或更多)智能指针来管理对象。我无法找到类似boost::intrusive_ptr 的解决方案。

【问题讨论】:

  • 您可以使用带有自定义删除器的unique_ptr 的包装器来实现intrusive_ptr,从而使您可以创建线程安全(或不安全)的引用计数。传递不是那么容易(需要移动,或手动操作引用计数),但是是可能的。

标签: c++ c++11 boost shared-ptr smart-pointers


【解决方案1】:

c++11 有没有等价于 boost::intrusive_ptr 的东西?

没有。

它确实有std::make_shared,这意味着std::shared_ptr几乎(见下面的注释)与侵入式智能指针一样高效,因为引用计数将存储在内存中与对象本身相邻的位置,提高引用的局部性和缓存的使用。它还提供std::enable_shared_from_this,当您只有一个指向shared_ptr拥有的对象的内置指针时,它允许您检索std::shared_ptr,但这不允许您使用不同的智能指针类型管理对象.

shared_ptr 期望完全负责管理对象。不同的智能指针类型可能只管理“强”引用计数而不管理“弱”引用计数,这会导致计数不同步并破坏shared_ptr 的不变量。


注意:使用make_shared 可以让shared_ptr几乎与侵入式指针一样高效。当使用make_shared 时,对象和引用计数信息可以分配在单个内存块中,但仍然会有两个引用计数(对于“强”和“弱”计数),这不是侵入性指针,因为它们不支持weak_ptr。此外,shared_ptr 对象本身总是必须存储两个指针(一个将由shared_ptr::get() 返回,另一个指向包含引用计数并知道所拥有对象的动态类型的“控制块”),所以比侵入式指针占用的空间更大。

【讨论】:

  • 不支持weak_ptr的侵入式指针 - 澄清一下:侵入式指针在设计上不能支持(线程安全的)weak_ptr。引用计数需要存储在对象之外,否则任何对弱指针的锁定尝试都会与对象的销毁竞争。换句话说:每个弱指针都共享引用计数的所有权。因此,如果 refcounter 与对象本身不可分割(如侵入式指针的情况),则弱指针因此也对对象本身具有(强)共享所有权,这与弱指针的概念相矛盾。
  • @ComicSansMS,确实 - 我的措辞很糟糕。我已经稍微改写了注释,我希望它更清楚。谢谢。
  • @ComicSansMS 这不仅仅是线程的问题:弱指针无法检查对象是否还活着,因为如果它已经被破坏,它们会读取freed 内存
  • shared_ptr 违反了“你不为你不使用的东西付费”的原则。它存储至少两个计数器和一个删除器(总共至少四个字?),加上每个shared_ptr 的大小是两个字而不是一个。对于不需要弱引用的具有小节点的链接结构,这是相当大的代价。 (想想绳索实现)
  • @ybungalobill “你不用为你不使用的东西买单”不适用于为工作选择错误的工具。如果您不需要需要共享所有权,请不要使用shared_ptr
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-08
  • 2012-04-09
  • 2012-04-11
  • 2011-06-18
相关资源
最近更新 更多