Which kind of pointer do I use when?

c++, c++-faq, c++11, pointers, smart-pointers

Solution

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 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 its 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.

Problem

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).

Original source

Related problems