或者如果我需要这样做,那么我应该只使用 shared_ptr 吗?
3 回答
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 delete
operator delete[]
智能指针支持Resource Acquisition Is Initialization或 RAII 习语,这是一种提供异常安全保证的方式。
是的,您可以通过引用传递它。
但是,如果函数只想使用托管对象,您可以考虑传递对对象本身的引用。
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
(例如,函数希望与其他共享指针共享资源)。
就个人而言,我几乎在任何地方都通过 const 引用传递 shared_ptr。正如其他人所说,如果您正在调用一个函数并传递一个 const 引用,那么调用者几乎肯定会将 shared_ptr 保持在范围内。
真正的好处是您可以节省以这种方式更新引用计数器的成本。快速阅读 wiki http://en.wikipedia.org/wiki/Reference_counting,您将了解到在引用计数器上不断执行 +1 / -1(可能是原子)操作会破坏您的缓存。