【发布时间】:2010-03-21 19:19:04
【问题描述】:
或者如果我需要这样做,那么我应该只使用 shared_ptr 吗?
【问题讨论】:
标签: c++ pass-by-reference shared-ptr scoped-ptr
或者如果我需要这样做,那么我应该只使用 shared_ptr 吗?
【问题讨论】:
标签: c++ pass-by-reference shared-ptr scoped-ptr
如果被调用者不需要存储包装的指针,则通过引用传递scoped_ptr 是安全的,只需使用它来调用一些方法。由scoped_ptr 保护的对象将在超出范围时被销毁 - 如果指针是堆栈变量,则在调用函数的末尾,或者当包含的类实例被释放时,如果它是成员变量。
一般来说,智能指针是用来管理对象所有权的,所以这里有一个简短的介绍:
boost::scoped_ptr 将受保护对象的生命周期限制在封闭范围内,只有一个所有者。
std::auto_ptr 一次也只有一个所有者,但它允许通过赋值(作为函数参数或返回值)传递所有权。
boost::shared_ptr 通过引用计数支持共享所有权,只有当引用计数变为零时,受保护的对象才会被销毁。这是最通用的智能指针,但也是最昂贵的,因为它会承受一些较小的开销(引用计数由原子操作维护,这相当昂贵。)还有循环依赖的可能性。
boost::weak_ptr 是一个 非拥有 智能指针,它可以在运行时升级到 boost::shared_ptr,并检查受保护的对象是否仍然存在。
还有像 boost::shared_array 这样的数组变体,因为 C++ 对单个对象和多个对象具有单独的释放函数(operator delete 与 operator delete[]。)
智能指针支持 Resource Acquisition Is Initialization 或 RAII 习语,这是提供 exception safety guarantees 的一种方式。
【讨论】:
f2(*a);.
T & operator*() const; 的scoped_ptr。
是的,您可以通过引用传递它。
但是,如果函数只想使用托管对象,您可以考虑传递对对象本身的引用。
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(可能是原子)操作会破坏您的缓存。
【讨论】: