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_ptrandweak_ptrthe 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. Useweak_ptrto observe the shared resource without influencing its lifetime, not to break cycles. Cycles withshared_ptrshouldn’t normally happen – two resources can’t own each other.Note that Boost additionally offers
shared_array, which might be a suitable alternative toshared_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_ptrisboost::scoped_ptron 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, unlikeboost::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 requiringstd::unique_ptr<T[]>partial specialization that willdelete[]the pointer instead ofdeleteing it (with thedefault_deleter).std::unique_ptr<T[]>also offersoperator[]instead ofoperator*andoperator->.Note that
std::auto_ptris still in the standard, but it is deprecated.§D.10 [depr.auto.ptr]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_ptrand use aweak_ptr– you can test if the parentshared_ptris alive withlock, which will return ashared_ptrthat is non-null if the resource still exists. If want to test whether the resource is dead, useexpired. The two may sound similar, but are very different in the face of concurrent execution, asexpiredonly guarantees its return value for that single statement. A seemingly innocent test likeis a potential race condition.