Which kind of pointer do I use when?(我什么时候使用哪种指针?)
问题描述
好的,所以上次我写 C++ 为生时,std::auto_ptr
是所有可用的 std lib,而 boost::shared_ptr
是所有可用的愤怒.我从未真正研究过 boost 提供的其他智能指针类型.我知道 C++11 现在提供了 boost 提出的一些类型,但不是全部.
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.
那么有人有一个简单的算法来确定何时使用哪个智能指针吗?最好包括关于哑指针(像 T*
这样的原始指针)和其他 boost 智能指针的建议.(类似于这个会很棒).
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_ptr
和weak_ptr
标准与它们的增强对应物.当您需要共享资源并且不知道哪一个将是最后一个还活着时,请使用它们.使用weak_ptr
观察共享资源,不影响其生命周期,不破坏循环.shared_ptr
循环通常不应该发生 - 两个资源不能相互拥有.
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.
请注意,Boost 还提供了shared_array
,这可能是 shared_ptr
.
Note that Boost additionally offers shared_array
, which might be a suitable alternative to shared_ptr<std::vector<T> const>
.
接下来,Boost 提供 intrusive_ptr
,如果您的资源已经提供引用计数管理,并且您希望将其应用于 RAII 原则,那么这是一个轻量级的解决方案.标准没有采用这个.
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.
唯一所有权:
Boost 还有一个 scoped_ptr
,这是不可复制的,您不能为其指定删除器.std::unique_ptr
是增强型的 boost::scoped_ptr
,应该是您需要智能指针时的默认选择.它允许您在其模板参数中指定删除器,并且是 可移动的,与 boost::scoped_ptr
不同.只要您不使用需要可复制类型的操作(显然),它也可以在 STL 容器中完全使用.
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).
再次注意,Boost 有一个数组版本:scoped_array
,该标准通过要求 std::unique_ptr
部分特化来统一,该部分特化将 delete[]
指针而不是 delete
ing(使用 default_delete
r).std::unique_ptr
还提供了 operator[]
而不是 operator*
和 operator->
代码>.
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->
.
请注意,std::auto_ptr
仍在标准中,但已弃用.§D.10 [depr.auto.ptr]
Note that std::auto_ptr
is still in the standard, but it is deprecated.
§D.10 [depr.auto.ptr]
不推荐使用类模板 auto_ptr
.[ 注意: 类模板 unique_ptr
(20.7.1) 提供了更好的解决方案.—结束注释 ]
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.
如果您想要对资源的非拥有引用,但您不知道该资源是否比引用它的对象寿命更长,请将资源打包在 shared_ptr
中并使用 weak_ptr
- 您可以使用 lock
测试父 shared_ptr
是否还活着,这将返回一个非空的 shared_ptr
如果资源仍然存在.如果要测试资源是否已死,使用expired
.两者听起来可能很相似,但在并发执行方面却大不相同,因为 expired
仅保证其对单个语句的返回值.一个看似无害的测试
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 its return value for that single statement. A seemingly innocent test like
if(!wptr.expired())
something_assuming_the_resource_is_still_alive();
是潜在的竞争条件.
这篇关于我什么时候使用哪种指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:我什么时候使用哪种指针?
- GDB 不显示函数名 2022-01-01
- 将 hdc 内容复制到位图 2022-09-04
- 使用 __stdcall & 调用 DLLVS2013 中的 GetProcAddress() 2021-01-01
- OpenGL 对象的 RAII 包装器 2021-01-01
- 从父 CMakeLists.txt 覆盖 CMake 中的默认选项(...)值 2021-01-01
- 哪个更快:if (bool) 或 if(int)? 2022-01-01
- 如何提取 __VA_ARGS__? 2022-01-01
- 将函数的返回值分配给引用 C++? 2022-01-01
- DoEvents 等效于 C++? 2021-01-01
- XML Schema 到 C++ 类 2022-01-01