7

或者如果我需要这样做,那么我应该只使用 shared_ptr 吗?

4

3 回答 3

14

scoped_ptr如果被调用者不需要存储包装的指针,而只是使用它来调用某些方法,则通过引用传递是安全的。由 保护的对象scoped_ptr将在超出范围时被销毁 - 如果指针是堆栈变量,则在调用函数的末尾,或者当包含的类实例被释放时,如果它是成员变量。

一般来说,智能指针是用来管理对象所有权的,所以这里有一个快速的总结:

  • boost::scoped_ptr将受保护对象的生命周期限制在封闭范围内,只有一个所有者。
  • std::auto_ptr一次也只有一个所有者,但它允许通过赋值(作为函数参数或返回值)传递所有权 。
  • boost::shared_ptr通过引用计数支持共享所有权,只有当引用计数变为零时,受保护的对象才会被销毁。这是最通用的智能指针,但也是最昂贵的,因为它有一些小的开销(引用计数是通过原子操作维护的,这是相当昂贵的。)还有循环依赖的可能性。
  • boost::weak_ptr是一个非拥有的智能指针,可以boost::shared_ptr在运行时升级到它,并检查受保护的对象是否仍然存在。

还有一些数组变体,例如因为 C++ 对单个对象和多个对象( vs. )boost::shared_array具有单独的释放函数operator deleteoperator delete[]

智能指针支持Resource Acquisition Is Initialization或 RAII 习语,这是一种提供异常安全保证的方式。

于 2010-03-21T19:43:40.913 回答
11

是的,您可以通过引用传递它。

但是,如果函数只想使用托管对象,您可以考虑传递对对象本身的引用。

void foo(const boost::scoped_ptr<Object>& o)
{
     o->foobar();
}

void bar(const Object& o)
{
     o.foobar();
}

不同之处在于,在第一种情况下,您将函数与特定的智能指针类型耦合在一起。

Object o;
boost::scoped_ptr<Object> scoped(new Object);
boost::shared_ptr<Object> shared(new Object);

foo(o);  //no
foo(scoped); //OK
foo(shared); //no

bar(o);  //OK
bar(*scoped); //OK
bar(*shared); //OK

scoped_ptr一般来说,如果打算对实例本身做某事scoped_ptr(例如释放或重置资源) ,我只会通过, 。类似地shared_ptr(例如,函数希望与其他共享指针共享资源)。

于 2010-03-21T20:21:54.483 回答
0

就个人而言,我几乎在任何地方都通过 const 引用传递 shared_ptr。正如其他人所说,如果您正在调用一个函数并传递一个 const 引用,那么调用者几乎肯定会将 shared_ptr 保持在范围内。

真正的好处是您可以节省以这种方式更新引用计数器的成本。快速阅读 wiki http://en.wikipedia.org/wiki/Reference_counting,您将了解到在引用计数器上不断执行 +1 / -1(可能是原子)操作会破坏您的缓存。

于 2011-07-30T19:03:55.597 回答