我使用哪种指针? [英] Which kind of pointer do I use when?
问题描述
好吧,所以最后一次我写了C ++的生活, std :: auto_ptr
是所有的std lib可用,和 boost: :shared_ptr
是所有愤怒。我从来没有真正看到其他智能指针类型提供。我理解C ++ 11现在提供了一些类型提升了,但不是所有的。
那么,有人有一个简单的算法来确定何时使用哪个智能指针?优选地包括关于哑指针(诸如 T *
的原始指针)和其他增强智能指针的建议。 (像这样的会很棒)。
共享所有权:
shared_ptr
和 weak_ptr
采用的标准与其对同事。当您需要共享资源,并且不知道哪个是最后一个存活时使用它们。使用 weak_ptr
来观察共享资源,而不影响其生命周期,而不是打破周期。 shared_ptr
的周期通常不会发生 - 两个资源不能彼此拥有。
请注意,Boost提供 shared_array
,这可能是 shared_ptr< std :: vector< T> const>
。
接下来,Boost提供 intrusive_ptr
,这是一个轻量级的解决方案,如果您的资源已经提供引用计数管理,并且您想采用它RAII原则。
scoped_ptr
,无法复制您不能指定删除程序。 std :: unique_ptr 是 boost :: scoped_ptr
类固醇,应为您的智能指针。它允许您在其模板参数中指定删除器,并且可移动,与 boost :: scoped_ptr
不同。只要你不使用需要可复制类型的操作(显然),它也可以在STL容器中完全使用。
再次注意,Boost有一个数组版本: scoped_array
标准统一通过要求 std :: unique_ptr< T []>
部分特化,将 delete []
而不是 delete
(使用 default_delete
r)。 std :: unique_ptr< T []>
还提供 operator []
而不是 *
和 operator->
。
std :: auto_ptr
仍在标准中,但已弃用 。 §D.10[depr.auto.ptr]
类模板
auto_ptr
已弃用。 [注意:类模板unique_ptr
(20.7.1)提供了一个更好的解决方案。 -end note ]
b对资源使用非所有引用的哑指针(原始指针)或引用,并且当您知道资源将延长引用对象/范围时。当您需要可空性或可重置性时,首选参考并使用原始指针。
如果您想要对资源的非所有权引用,但不知道资源将资源引入 shared_ptr
并使用 weak_ptr
- 您可以测试父 shared_ptr
是活着的 lock
,将返回 shared_ptr
如果资源仍然存在,那么是非null。如果要测试资源是否已经死亡,请使用 expired
。这两个可能听起来类似,但是在并发执行面上是非常不同的,因为 expired
只保证它是该单个语句的返回值。一个看似无辜的测试,像
if(!wptr.expired())
something_assuming_the_resource_is_still_alive
是一种潜在的竞争条件。
Ok, so the last time I wrote C++ for a living, std::auto_ptr
was all the std lib had available, and boost::shared_ptr
was all the rage. I never really looked into the other smart pointer types boost provided. I understand that C++11 now provides some of the types boost came up with, but not all of them.
So does someone have a simple algorithm to determine when to use which smart pointer? Preferably including advice regarding dumb pointers (raw pointers like T*
) and the rest of the boost smart pointers. (Something like this would be great).
Shared ownership:
The shared_ptr
and weak_ptr
the standard adopted are pretty much the same as their Boost counterparts. Use them when you need to share a resource and don't know which one will be the last to be alive. Use weak_ptr
to observe the shared resource without influencing its lifetime, not to break cycles. Cycles with shared_ptr
shouldn't normally happen - two resources can't own each other.
Note that Boost additionally offers shared_array
, which might be a suitable alternative to shared_ptr<std::vector<T> const>
.
Next, Boost offers intrusive_ptr
, which are a lightweight solution if your resource offers reference-counted management already and you want to adopt it to the RAII principle. This one was not adopted by the standard.
Unique ownership:
Boost also has a scoped_ptr
, which is not copyable and for which you can not specify a deleter. std::unique_ptr
is boost::scoped_ptr
on steroids and should be your default choice when you need a smart pointer. It allows you to specify a deleter in its template arguments and is movable, unlike boost::scoped_ptr
. It is also fully usable in STL containers as long as you don't use operations that need copyable types (obviously).
Note again, that Boost has an array version: scoped_array
, which the standard unified by requiring std::unique_ptr<T[]>
partial specialization that will delete[]
the pointer instead of delete
ing it (with the default_delete
r). std::unique_ptr<T[]>
also offers operator[]
instead of operator*
and operator->
.
Note that std::auto_ptr
is still in the standard, but it is deprecated.
§D.10 [depr.auto.ptr]
The class template
auto_ptr
is deprecated. [ Note: The class templateunique_ptr
(20.7.1) provides a better solution. —end note ]
No ownership:
Use dumb pointers (raw pointers) or references for non-owning references to resources and when you know that the resource will outlive the referencing object / scope. Prefer references and use raw pointers when you need either nullability or resettability.
If you want a non-owning reference to a resource, but you don't know if the resource will outlive the object that references it, pack the resource in a shared_ptr
and use a weak_ptr
- you can test if the parent shared_ptr
is alive with lock
, which will return a shared_ptr
that is non-null if the resource still exists. If want to test whether the resource is dead, use expired
. The two may sound similar, but are very different in the face of concurrent execution, as expired
only guarantees it's return value for that single statement. A seemingly innocent test like
if(!wptr.expired())
something_assuming_the_resource_is_still_alive();
is a potential race condition.
这篇关于我使用哪种指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!