1

我喜欢 Boost 的 smart_ptr 功能以及与 and 相互转换的能力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实例中查找引用计数?

4

3 回答 3

2

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

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

shared_ptr<A> aPtr1 = boost::make_shared<A>();
于 2012-11-11T20:08:33.363 回答
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;我没有尝试使用 boost,但我想它也应该在那里工作。我认为这有点骇人听闻。使用 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;
} 
于 2012-11-11T20:11:01.467 回答
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

于 2012-11-11T20:41:16.517 回答