3 回答
TA贡献1798条经验 获得超7个赞
C ++ 03
std::auto_ptr
- 也许其初次综合症患者的原件之一仅提供有限的垃圾收集设施。第一个缺点是它要求delete
销毁使它们无法接受数组分配的对象(new[]
)。它需要指针的所有权,因此两个自动指针不应包含相同的对象。赋值将转移所有权并将rvalue自动指针重置为空指针。这可能导致最严重的缺点; 由于上述无法复制,它们不能在STL容器中使用。对任何用例的最后一击是它们将在下一个C ++标准中被弃用。
std::auto_ptr_ref
- 这不是一个智能指针,它实际上是一个设计细节,用于std::auto_ptr
在某些情况下允许复制和分配。具体来说,它可以用于将非const std::auto_ptr
转换为左值,使用Colvin-Gibbons技巧(也称为移动构造函数)来转移所有权。
相反,或许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
,基于这种实现,这允许对a的非拥有引用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
它们,但一切都可以。但是,您也可以使用boost::shared_ptr<std::vector<>>
类似功能并重新获得boost::weak_ptr
用于引用的功能。
boost::scoped_array
- 这是一个boost::scoped_ptr
数组。与boost::shared_array
所有必要的阵列良好性相同。这一个是不可复制的,因此不能在STL容器中使用。我发现几乎你发现自己想要使用它的任何地方你可能只是使用它std::vector
。我从来没有确定哪个实际上更快或开销更少但这个范围的数组似乎远不如STL向量。当你想在堆栈上保持分配时,请考虑boost::array
。
Qt的
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
用于的所有内容。
TA贡献1842条经验 获得超12个赞
TA贡献1786条经验 获得超11个赞
除了给出的,还有一些安全导向的:
SaferCPlusPlus
mse::TRefCountingPointer
是一个引用计数智能指针之类的std::shared_ptr
。不同之处在于mse::TRefCountingPointer
更安全,更小,更快,但没有任何线程安全机制。它出现在“not null”和“fixed”(非重定向)版本中,可以安全地假设它们始终指向有效分配的对象。所以基本上,如果您的目标对象在异步线程之间共享,那么使用std::shared_ptr
,否则mse::TRefCountingPointer
更优化。
mse::TScopeOwnerPointer
类似于boost::scoped_ptr
,但与mse::TScopeFixedPointer
“强 - 弱”指针关系一起工作的类似std::shared_ptr
和std::weak_ptr
。
mse::TScopeFixedPointer
指向在堆栈上分配的对象,或者在堆栈上分配“拥有”指针的对象。(故意)限制其功能,以增加编译时的安全性,而无需运行时成本。“范围”指针的要点主要是识别一组简单且确定性足以不需要(运行时)安全机制的环境。
mse::TRegisteredPointer
行为类似于原始指针,除了在销毁目标对象时其值自动设置为null_ptr。在大多数情况下,它可以用作原始指针的一般替代品。像原始指针一样,它没有任何内在的线程安全性。但作为交换,它对于在堆栈上分配的对象(并获得相应的性能优势)没有问题。启用运行时检查时,此指针可以安全地访问无效内存。因为mse::TRegisteredPointer
在指向有效对象时具有与原始指针相同的行为,所以可以使用编译时指令将其“禁用”(自动替换为相应的原始指针),允许它用于帮助捕获调试/测试中的错误/ beta模式,同时在发布模式下不会产生间接费用。
这里是描述为何以及如何使用它们的文章。(注意,无耻插头。)
- 3 回答
- 0 关注
- 566 浏览
添加回答
举报