通过引用传递scoped_ptr(从一个方法中的一个方法到另一个方法)是不错的做法?

时间:2010-03-21 19:19:04

标签: c++ pass-by-reference shared-ptr scoped-ptr

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

3 个答案:

答案 0 :(得分:13)

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

一般情况下,智能指针可用于管理对象所有权,因此这里有一个快速下载:

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

还有像boost::shared_array这样的数组变体,因为C ++对单个和多个对象(operator deleteoperator delete[]有单独的释放函数。)

智能指针支持Resource Acquisition Is Initialization或RAII,这是一种提供exception safety guarantees的方式。

答案 1 :(得分: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(例如,该函数想要与其他共享指针共享资源)。

答案 2 :(得分:0)

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

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