C ++ 03
std::auto_ptr
-也许患有初稿综合症的原始物之一只能提供有限的垃圾收集设施。第一个缺点是它要求delete
销毁,使它们无法容纳数组分配的对象(new[]
)。它拥有指针的所有权,因此两个自动指针不应包含相同的对象。分配将转移所有权,并将右值自动指针重置为空指针。这可能导致最严重的缺点;由于上述无法复制,因此无法在STL容器中使用它们。对所有用例的最后一击是,它们计划在C ++的下一个标准中弃用。
std::auto_ptr_ref
-这不是一个智能指针,它实际上是一个设计细节,用于std::auto_ptr
在某些情况下进行复制和分配。具体地说,它可用于一非const转换std::auto_ptr
到一个左值使用科尔-长臂猿特技也称为移动构造函数,以转移所有权。
相反,也许std::auto_ptr
并不是真正打算用作自动垃圾收集的通用智能指针。我大多数有限的理解和假设都是基于Herb Sutter的对auto_ptr的有效使用,尽管并非总是以最优化的方式进行,但我确实定期使用它。
C ++ 11
std::unique_ptr
-这是我们的朋友,将取代std::auto_ptr
它,它与以前非常相似,只是在关键方面进行了改进,以纠正std::auto_ptr
诸如处理数组,通过私有副本构造函数进行左值保护,可以与STL容器和算法一起使用等弱点。由于这是性能开销并且内存占用空间有限,这是替换原始指针的理想选择,或者更恰当地描述为拥有原始指针。正如“唯一”所暗示的,与前一个指针一样,指针也只有一个所有者std::auto_ptr
。
std::shared_ptr
-我相信这是基于TR1的,boost::shared_ptr
但也进行了改进,包括别名和指针算法。简而言之,它将引用计数的智能指针包装在动态分配的对象周围。由于“共享”表示当最后一个共享指针的最后一个引用超出范围时,该指针可以由多个共享指针拥有,那么该对象将被适当删除。这些也是线程安全的,并且在大多数情况下可以处理不完整的类型。std::make_shared
可用于std::shared_ptr
使用默认分配器有效地构造一个堆分配的。
std::weak_ptr
-同样基于TR1和boost::weak_ptr
。这是对a拥有的对象的引用,std::shared_ptr
因此,如果std::shared_ptr
引用计数降至零,则不会阻止删除该对象。为了获得对原始指针的访问,您首先需要std::shared_ptr
通过调用来访问,如果拥有的指针已过期并且已经被破坏lock
,则它将返回一个空std::shared_ptr
。这对于避免使用多个智能指针时不确定的挂起引用计数非常有用。
促进
boost::shared_ptr
-可能是最容易在各种情况(STL,PIMPL,RAII等)中使用的,这是一个共享的引用计数智能指针。在某些情况下,我已经听到了一些有关性能和开销的投诉,但是我一定忽略了它们,因为我不记得争论了什么。显然,它很受欢迎,已成为未决的标准C ++对象,并且没有想到关于智能指针的规范方面的缺点。
boost::weak_ptr
-非常类似于之前的描述std::weak_ptr
,基于此实现,它允许对进行非所有权引用boost::shared_ptr
。您毫不奇怪地调用它lock()
来访问“强”共享指针,并且必须检查以确保其有效,因为它可能已经被销毁。只要确保不存储返回的共享指针,并在使用完它后立即使其超出范围,否则您将回到循环引用问题,在该循环引用问题中,引用计数将挂起并且对象不会被破坏。
boost::scoped_ptr
-这是一个简单的智能指针类,几乎没有开销,可能是为boost::shared_ptr
在使用时提供更好的性能而设计的。它与std::auto_ptr
以下事实特别具有可比性:它不能安全地用作STL容器的元素或不能使用多个指向同一对象的指针。
boost::intrusive_ptr
-我从没有使用过它,但是据我了解,它旨在用于创建自己的智能指针兼容类。您需要自己实现引用的计数,如果您希望类是通用的,还需要实现一些方法,此外,您还必须实现自己的线程安全性。从好的方面来说,这可能为您提供了最自定义的选择和选择您想要的“聪明”程度的方式。intrusive_ptr
通常比效率更高,shared_ptr
因为它允许您为每个对象分配一个堆。(感谢Arvid)
boost::shared_array
-这是一个boost::shared_ptr
数组。基本上new []
,operator[]
和当然delete []
是烘烤的。可以在STL容器中使用它,据我所知boost:shared_ptr
,尽管您不能使用boost::weak_ptr
它们,但它所做的一切。但是,您也可以将a boost::shared_ptr<std::vector<>>
用于类似功能,并重新获得boost::weak_ptr
用于引用的功能。
boost::scoped_array
-这是一个boost::scoped_ptr
数组。与boost::shared_array
所有必需的数组一样,它们也可以烘烤。这是不可复制的,因此不能在STL容器中使用。我发现几乎您发现自己想使用它的任何地方都可以使用std::vector
。我从来没有确定哪个实际上更快或更少开销,但是这个作用域数组似乎比STL向量要少得多。当您想在堆栈上保留分配时,请考虑boost::array
使用。
t
QPointer
-在Qt 4.0中引入了一个“弱”智能指针,它仅适用于QObject
和派生类,在Qt框架中几乎所有东西都这样,因此这实际上不是一个限制。但是存在局限性,即它不提供“强”指针,尽管您可以检查基础对象是否有效,isNull()
但在通过该检查后,尤其是在多线程环境中,可能会发现对象被破坏。我相信Qt人们认为这已经过时了。
QSharedDataPointer
-这是一个“强大”的智能指针,boost::intrusive_ptr
尽管它具有一些内置的线程安全性,但潜在地可以与之媲美,但它确实需要您包括引用计数方法(ref
和deref
),您可以通过子类化来实现QSharedData
。与许多Qt一样,最好通过充分的继承来使用对象,并将所有子类都继承为预期的设计。
QExplicitlySharedDataPointer
-与QSharedDataPointer
它非常相似,只是它不会隐式调用detach()
。我将这个版本QSharedDataPointer
称为2.0版,因为在引用计数降至零后确切何时分离的控制稍微增加了,特别不值得使用一个全新的对象。
QSharedPointer
-原子引用计数,线程安全,可共享指针,自定义删除(数组支持),听起来像智能指针应该具备的所有功能。这就是我最初在Qt中用作智能指针的原因,boost:shared_ptr
尽管与Qt中的许多对象一样,其开销可能要大得多,但我发现它具有可比性。
QWeakPointer
-您是否感觉到重复出现的模式?就像当需要在两个智能指针之间进行引用时std::weak_ptr
,boost::weak_ptr
这将一起使用QSharedPointer
,否则这将导致您的对象永远不会被删除。
QScopedPointer
-这个名称也应该看起来很熟悉,实际上实际上是基于boost::scoped_ptr
Qt版本的共享指针和弱指针。其功能是提供一个单一的所有者智能指针没有的开销QSharedPointer
,这使得它更适合的兼容性,异常安全的代码,你可以使用的东西std::auto_ptr
或boost::scoped_ptr
进行。