C++03
std::auto_ptr
- Perhaps one of the originals it suffered from first draft syndrome only providing limited garbage collection facilities. The first downside being that it calls delete
upon destruction making them unacceptable for holding array allocated objects (new[]
). It takes ownership of the pointer so two auto pointers shouldn't contain the same object. Assignment will transfer ownership and reset the rvalue auto pointer to a null pointer. Which leads to perhaps the worst drawback; they can't be used within STL containers due to the aforementioned inability to be copied. The final blow to any use case is they are slated to be deprecated in the next standard of C++.
std::auto_ptr_ref
- This is not a smart pointer it's actually a design detail used in conjunction with std::auto_ptr
to allow copying and assignment in certain situations. Specifically it can be used to convert a non-const std::auto_ptr
to an lvalue using the Colvin-Gibbons trick also known as a move constructor to transfer ownership.
On the contrary perhaps std::auto_ptr
wasn't really intended to be used as a general purpose smart pointer for automatic garbage collection. Most of my limited understanding and assumptions are based on Herb Sutter's Effective Use of auto_ptr and I do use it regularly although not always in the most optimized way.
C++11
std::unique_ptr
- This is our friend who will be replacing std::auto_ptr
it will be quite similar except with the key improvements to correct the weaknesses of std::auto_ptr
like working with arrays, lvalue protection via private copy constructor, being usable with STL containers and algorithms, etc. Since it's performance overhead and memory footprint are limited this is an ideal candidate for replacing, or perhaps more aptly described as owning, raw pointers. As the "unique" implies there is only one owner of the pointer just like the previous std::auto_ptr
.
std::shared_ptr
- I believe this is based off TR1 and boost::shared_ptr
but improved to include aliasing and pointer arithmetic as well. In short it wraps a reference counted smart pointer around a dynamically allocated object. As the "shared" implies the pointer can be owned by more than one shared pointer when the last reference of the last shared pointer goes out of scope then the object will be deleted appropriately. These are also thread safe and can handle incomplete types in most cases. std::make_shared
can be used to efficiently construct a std::shared_ptr
with one heap allocation using the default allocator.
std::weak_ptr
- Likewise based off TR1 and boost::weak_ptr
. This is a reference to an object owned by a std::shared_ptr
and will therefore not prevent the deletion of the object if the std::shared_ptr
reference count drops to zero. In order to get access to the raw pointer you'll first need to access the std::shared_ptr
by calling lock
which will return an empty std::shared_ptr
if the owned pointer has expired and been destroyed already. This is primarily useful to avoid indefinite hanging reference counts when using multiple smart pointers.
Boost
boost::shared_ptr
- Probably the easiest to use in the most varying scenarios (STL, PIMPL, RAII, etc) this is a shared referenced counted smart pointer. I've heard a few complaints about performance and overhead in some situations but I must have ignored them because I can't remember what the argument was. Apparently it was popular enough to become a pending standard C++ object and no drawbacks over the norm regarding smart pointers come to mind.
boost::weak_ptr
- Much like previous description of std::weak_ptr
, based on this implementation, this allows a non-owning reference to a boost::shared_ptr
. You not surprisingly call lock()
to access the "strong" shared pointer and must check to make sure it's valid as it could have already been destroyed. Just make sure not to store the shared pointer returned and let it go out of scope as soon as you're done with it otherwise you're right back to the cyclic reference problem where your reference counts will hang and objects will not be destroyed.
boost::scoped_ptr
- This is a simple smart pointer class with little overhead probably designed for a better performing alternative to boost::shared_ptr
when usable. It's comparable to std::auto_ptr
especially in the fact that it can't be safely used as an element of a STL container or with multiple pointers to the same object.
boost::intrusive_ptr
- I've never used this but from my understanding it's designed to be used when creating your own smart pointer compatible classes. You need to implement the reference counting yourself, you'll also need to implement a few methods if you want your class to be generic, furthermore you'd have to implement your own thread safety. On the plus side this probably gives you the most custom way of picking and choosing exactly how much or how little "smartness" you want. intrusive_ptr
is typically more efficient than shared_ptr
since it allows you to have a single heap allocation per object. (thanks Arvid)
boost::shared_array
- This is a boost::shared_ptr
for arrays. Basically new []
, operator[]
, and of course delete []
are baked in. This can be used in STL containers and as far as I know does everything boost:shared_ptr
does although you can't use boost::weak_ptr
with these. You could however alternatively use a boost::shared_ptr<std::vector<>>
for similar functionality and to regain the ability to use boost::weak_ptr
for references.
boost::scoped_array
- This is a boost::scoped_ptr
for arrays. As with boost::shared_array
all the necessary array goodness is baked in. This one is non-copyable and so can't be used in STL containers. I've found almost anywhere you find yourself wanting to use this you probably could just use std::vector
. I've never determined which is actually faster or has less overhead but this scoped array seems far less involved than a STL vector. When you want to keep allocation on the stack consider boost::array
instead.
Qt
QPointer
- Introduced in Qt 4.0 this is a "weak" smart pointer which only works with QObject
and derived classes, which in the Qt framework is almost everything so that's not really a limitation. However there are limitations namely that it doesn't supply a "strong" pointer and although you can check if the underlying object is valid with isNull()
you could find your object being destroyed right after you pass that check especially in multi-threaded environments. Qt people consider this deprecated I believe.
QSharedDataPointer
- This is a "strong" smart pointer potentially comparable to boost::intrusive_ptr
although it has some built in thread safety but it does require you to include reference counting methods (ref
and deref
) which you can do by subclassing QSharedData
. As with much of Qt the objects are best used through ample inheritance and subclassing everything seems to be the intended design.
QExplicitlySharedDataPointer
- Very similar to QSharedDataPointer
except it doesn't implicitly call detach()
. I'd call this version 2.0 of QSharedDataPointer
as that slight increase in control as to exactly when to detach after the reference count drops to zero isn't particularly worth a whole new object.
QSharedPointer
- Atomic reference counting, thread safe, sharable pointer, custom deletes (array support), sounds like everything a smart pointer should be. This is what I primarily use as a smart pointer in Qt and I find it comparable with boost:shared_ptr
although probably significantly more overhead like many objects in Qt.
QWeakPointer
- Do you sense a reoccurring pattern? Just as std::weak_ptr
and boost::weak_ptr
this is used in conjunction with QSharedPointer
when you need references between two smart pointers that would otherwise cause your objects to never be deleted.
QScopedPointer
- This name should also look familiar and actually was in fact based on boost::scoped_ptr
unlike the Qt versions of shared and weak pointers. It functions to provide a single owner smart pointer without the overhead of QSharedPointer
which makes it more suitable for compatibility, exception safe code, and all the things you might use std::auto_ptr
or boost::scoped_ptr
for.
osg::ref_ptr
. – Bassesalpesstd::auto_ptr
.std::auto_ptr_ref
is a design detail ofstd::auto_ptr
.std::auto_ptr
has nothing to do with garbage collection, it's main purpose is specifically to allow exception safe transfer of ownership, especially in function call and function return situations.std::unique_ptr
can only solve the "problems" that you cite with standard containers because C++ has changed to allow a distinction between move and copy and standard containers have changed to take advantage of this. – Outroarstd::auto_ptr
was not really as a smart pointer which would explain the non-copyable nature and transfer of ownership on assignment. I think perhaps wide misuse and misconception of it's intended use partially led to the proposed changes. – Geriatricsstd::auto_ptr
couldn't be safely used in certain cases. – Geriatricsshared_ptr
counts becausemake_shared
is part of its interface but your definition seems to be closer to what I would call a 'pimpl' class. – Outroarauto_ptr_ref
being an implementation detail). Still, I agree that you should post this as an answer and reformulate the question to be an actual question. This can then serve as a future reference. – Exothermicreset()
methods don't callnew
for you so I would have to remove "allocation and" ... although I'm sure someone has probably implemented something like that before as well. – Geriatricsauto_ptr
to be a smart pointer so when you said "the intended use ofstd::auto_ptr
was not really as a smart pointer" I just wanted to clarify exactly what you meant by a smart pointer. I wasn't trying to be picky or argumentative, just clear. – Outroarc++-faq
. I'd do it myself, but I'm not sure which of the existing 5 tags to replace. @Josh: Even though questions can be closed quickly, as you've noticed, they can also be re-opened. No real problem here. The question was changed to be an actual question, and is now answerable. Thus, it has now been re-opened. – Aesopc++-faq
tag, and removedc++-11
, as it is going to become the newc++
soon... hopefully. – Tonsil