使用Boost shared_ptr进行嵌入式引用计数

时间:2012-11-11 19:54:50

标签: c++ boost smart-pointers

我喜欢Boost的smart_ptr功能以及转换为shared_ptrweak_ptr的功能,但由于引用计数不包含在指定的类本身中,因此以下代码不起作用(它不应该)。

A *a = new A;
shared_ptr<A> aPtr1(a);

{
    shared_ptr<A> aPtr2(a);

    // The reference counts of aPtr1 and aPtr2 are both 1.
}   // At this point, `a` is destructed by aPtr2.

aPtr1->foo();   // And... SIGTERM

我相信JUCE框架具有此功能。 [ReferenceCountedObjectReferenceCountedObjectPtr] 但是,我宁愿在我的应用程序中使用Boost。是否可以允许Boost smart_ptrs在指向的类而不是私有的boost::detail::shared_count实例中查找引用计数?

3 个答案:

答案 0 :(得分:2)

boost::intrusive_ptr可能符合您的要求。

但是要注意,使用shared_ptr时,您应该按如下方式构造它们:

shared_ptr<A> aPtr1 = boost::make_shared<A>();

答案 1 :(得分:2)

简单的解决方案:

A *a = new A;
shared_ptr<A> aPtr1(a);
{
    // construct new shared pointer from old one.
    shared_ptr<A> aPtr2(aPtr1);
}
aPtr1->foo();

如果您想要更复杂的内容,请参阅http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html

  

标题<boost/enable_shared_from_this.hpp>定义了类模板enable_shared_from_this。它用作基类,允许从成员函数中获取当前对象的shared_ptr


编辑:我应该提到enable_shared_from_this在推导方面存在一些不幸的问题。但是,以下适用于c ++ 11;我没有尝试过它,但我想它也应该在那里工作。我觉得这有点像黑客;当你使用shared_ptr时使用原始指针必然会流下眼泪:

struct X : std::enable_shared_from_this {
  /* stuff */
};

struct Y : X {
  /* stuff */
  void yonly() {};
};

int main() {
  Y* y = new Y;
  shared_ptr<Y> sy(y);
  sy->yonly();
  {
    auto sy2 = std::shared_ptr<Y>(y->shared_from_this(), y);
    sy2->yonly();
  } 
  std::cout << "Block ended" << std::endl;
  return 0;
} 

答案 2 :(得分:0)

这不是例外安全:

// call this as in shared_ptr<T> foo = create_intrusive_shared( new T(blah) );
// This takes ownership of the pointer you pass it.
template<typename T>
std::shared_ptr<T> create_intrusive_shared( T* t )
{
  auto retval = std::shared_ptr<T>( t, []( T* cleanup )
  {
    if (cleanup)
      cleanup->RemoveRef();
  });
  return retval;
}

// Call this if you have an existing instance of T, whose ownership is being
// maintained elsewhere.  Do not call it with new T() as an argument, unless
// new instances of T are created with a 0 ref count
template<typename T>
std::shared_ptr<T> make_intrusive_shared( T* t )
{
  if (t)
    t->AddRef();
  auto retval = create_intrusive_shared(t);
  return retval;
}

使它们异常安全需要更多的工作。您需要重新实现make_shared,但使用清理功能标记生成的shared_ptr