我使用哪种指针? [英] Which kind of pointer do I use when?

查看:85
本文介绍了我使用哪种指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,所以最后一次我写了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原则。

http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/scoped_ptr.htm> 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 deleteing it (with the default_deleter). 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 template unique_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆