Short and sweet question. I should learn from this.
–
Fukuzawa YukioMar 18 '13 at 20:37

Here's Alexandrescu's (free) chapter on the nitty gritty of creating smart pointers of different flavors: informit.com/articles/article.aspx?p=31529 In his implementation, he uses template arguments as "policies" to specify which attributes he wants (e.g., reference counting), whereas the standard library uses separate classes. Note that he was also writing before rvalue references were available to make something like std::unique_ptr possible.
–
metalMar 19 '13 at 16:30

9 Answers
9

A smart pointer is a class that wraps a 'raw' (or 'bare') C++ pointer, to manage the lifetime of the object being pointed to. There is no single smart pointer type, but all of them try to abstract a 'raw' pointer in a practical way.

Smart pointers should be preferred over 'raw' pointers. If you feel you need to use pointers (first consider if you really do) you would normally want to use a smart pointer as this can alleviate many of the problems with 'raw' pointers, mainly forgetting to delete the object and leaking memory.

With 'raw' C++ pointers, the programmer has to explicitly destroy the object when it is no longer useful.

// Need to create the object to achieve some goal
MyObject* ptr = new MyObject();
ptr->DoSomething(); // Use the object in some way
delete ptr; // Destroy the object. Done with it.
// Wait, what if DoSomething() raises an exception...?

A smart pointer by comparison defines a policy as to when the object is destroyed. You still have to create the object, but you no longer have to worry about destroying it.

SomeSmartPtr<MyObject> ptr(new MyObject());
ptr->DoSomething(); // Use the object in some way.
// Destruction of the object happens, depending
// on the policy the smart pointer class uses.
// Destruction would happen even if DoSomething()
// raises an exception

Note that scoped_ptr instances cannot be copied. This prevents the pointer from being deleted multiple times (incorrectly). You can, however, pass references to it around to other functions you call.

Scoped pointers are useful when you want to tie the lifetime of the object to a particular block of code, or if you embedded it as member data inside another object, the lifetime of that other object. The object exists until the containing block of code is exited, or until the containing object is itself destroyed.

A more complex smart pointer policy involves reference counting the pointer. This does allow the pointer to be copied. When the last "reference" to the object is destroyed, the object is deleted. This policy is implemented by boost::shared_ptr and std::shared_ptr.

void f()
{
typedef std::tr1::shared_ptr<MyObject> MyObjectPtr; // Nice short alias.
MyObjectPtr p1; // Empty
{
MyObjectPtr p2(new MyObject());
// There is now one "reference" to the created object
p1=p2; // Copy the pointer.
// There are now two references to the object.
} // p2 is destroyed, leaving one reference to the object.
} // p1 is destroyed, leaving a reference count of zero.
// The object is deleted.

Reference counted pointers are very useful when the lifetime of your object is much more complicated, and is not tied directly to a particular section of code or to another object.

There is one drawback to reference counted pointers — the possibility of creating a dangling reference:

// Create the smart pointer on the heap
MyObjectPtr* pp = new MyObjectPtr(new MyObject())
// Hmm, we forgot to destroy the smart pointer,
// because of that, the object is never destroyed!

To work around this problem, both Boost and C++11 have defined a weak_ptr to define a weak (uncounted) reference to a shared_ptr.

This answers is rather old, and so uses what was 'good' at the time, which was smart pointers provided by the boost library. Since C++11 the standard library has provided sufficient smart pointers types, and so you should favour the use of std::unique_ptr, std::shared_ptr and std::weak_ptr.

There is also std::auto_ptr. It is very much like a scoped pointer, except that it also has the "special" dangerous ability to be copied — which also unexpectedly transfers ownership! It is deprecated in the newest standards, so you shouldn't use it.

wow... anyone should understand the concept after reading this
–
ShreeFeb 15 '12 at 10:03

7

Awesome answer. It would be nice if it were updated for c++11. I found this answer looking for info about the new 11 standard and it would be nice if future visitors could find the updated info. I know auto_ptr has been deprecated. I believe shated_ptr and weak_ptr exist as described, and I think the scoped_ptr is now unique_ptr in the standard. If this is true, can this answer be updated please?
–
SaulBackSep 11 '12 at 20:50

One of the simple smart-pointer type is std::auto_ptr (chapter 20.4.5 of C++ standard), which allows to deallocated memory automatically when it out of scope and which is more robust than simple pointer usage when exceptions are throw, although less flexible.

Another convenient type is boost::shared_ptr which implements reference counting and automatically deallocate memory when no references to object remain, this helps to avoid memory leaks, it is easy to use to implement RAII.

Definitions provided Chris,Sergdev and Llyod is correct. I prefer a simpler definition though, just to keep my life simple:
Smart pointer is simply a class that overloads -> and * operators. Which means that your object semantically looks like a pointer but you can make it do way cooler things, including reference counting, automatic destruction etc.
shared_ptr and auto_ptr are sufficient in most cases, but come along with their own set of small idiosyncrasies..

A smart pointer is like a regular (typed) pointer, like "char*", except when the pointer itself goes out of scope then what it points to is deleted as well. You can use it like you would a regular pointer, by using "->", but not if you need an actual pointer to the data. For that, you can use "&*ptr".

It is useful for:

Objects that must be allocated with new, but that you'd like to have the same lifetime as something on that stack. If the object is assigned to a smart pointer, then they will be deleted when the program exits that function/block.

Data members of classes, so that when the object is deleted all the owned data is deleted as well, without any special code in the destructor (you will need to be sure the destructor is virtual, which is almost always a good thing to do).

You may not want to use a smart pointer when:

... the pointer shouldn't actually own the data... i.e., when you are just using the data, but you want it to survive the function where you are referencing it.

... the smart pointer isn't itself going to be destroyed at some point. You don't want it to sit in memory that never gets destroyed (such as in an object that is dynamically allocated but won't be explicitly deleted).

... two smart pointers might point to the same data. (There are, however, even smarter pointers that will handle that... that is called reference counting.)

Most kinds of smart pointers handle disposing of the pointer-to object for you. It's very handy because you don't have to think about disposing of objects manually anymore.

The most commonly-used smart pointers are std::tr1::shared_ptr (or boost::shared_ptr), and, less commonly, std::auto_ptr. I recommend regular use of shared_ptr.

shared_ptr is very versatile and deals with a large variety of disposal scenarios, including cases where objects need to be "passed across DLL boundaries" (the common nightmare case if different libcs are used between your code and the DLLs).

A smart pointer is an object that acts like a pointer, but additionally provides control on construction, destruction, copying, moving and dereferencing.

One can implement one's own smart pointer, but many libraries also provide smart pointer implementations each with different advantages and drawbacks.

For example, Boost provides the following smart pointer implementations:

shared_ptr<T> is a pointer to T using a reference count to determine when the object is no longer needed.

scoped_ptr<T> is a pointer automatically deleted when it goes out of scope. No assignment is possible.

intrusive_ptr<T> is another reference counting pointer. It provides better performance than shared_ptr, but requires the type T to provide its own reference counting mechanism.

weak_ptr<T> is a weak pointer, working in conjunction with shared_ptr to avoid circular references.

shared_array<T> is like shared_ptr, but for arrays of T.

scoped_array<T> is like scoped_ptr, but for arrays of T.

These are just one linear descriptions of each and can be used as per need, for further detail and examples one can look at the documentation of Boost.

Additionally, the C++ standard library provides three smart pointers; std::unique_ptr for unique ownership, std::shared_ptr for shared ownership and std::weak_ptr. std::auto_ptr existed in C++03 but is now deprecated.

A smart pointer is an object that acts, looks and feels like a normal pointer but offers more functionality. In C++, smart pointers are implemented as template classes that encapsulate a pointer and override standard pointer operators. They have a number of advantages over regular pointers. They are guaranteed to be initialized as either null pointers or pointers to a heap object. Indirection through a null pointer is checked. No delete is ever necessary. Objects are automatically freed when the last pointer to them has gone away. One significant problem with these smart pointers is that unlike regular pointers, they don't respect inheritance. Smart pointers are unattractive for polymorphic code. Given below is an example for the implementation of smart pointers.

In computer science, a smart pointer
is an abstract data type that
simulates a pointer while providing
additional features, such as automatic
garbage collection or bounds checking.
These additional features are intended
to reduce bugs caused by the misuse of
pointers while retaining efficiency.
Smart pointers typically keep track of
the objects that point to them for the
purpose of memory management. The
misuse of pointers is a major source
of bugs: the constant allocation,
deallocation and referencing that must
be performed by a program written
using pointers makes it very likely
that some memory leaks will occur.
Smart pointers try to prevent memory
leaks by making the resource
deallocation automatic: when the
pointer to an object (or the last in a
series of pointers) is destroyed, for
example because it goes out of scope,
the pointed object is destroyed too.

When should I use one?
In code which otherwise involves tracking pointer ownership, allocating or de-allocating.

But which smart pointer should I use in which of those cases?

Use std::unique_ptr when you're not planning multiple references to the same object. For example, for a pointer which gets allocated on entering some scope and de-allocated on exiting the scope.

Use std::shared_ptr when you do want to refer to your object from multiple places - and do not want it to be de-allocated until all these references are themselves gone.

Use std::weak_ptr when you do want to refer to your object from multiple places - for those references for which it's ok to ignore and deallocate (so they'll just note the object is gone when you try to dereference).

Don't use the boost:: pointers or std::auto_ptr except in special cases which you can read up on if you must.

Hey, I didn't ask which one to use!
Ah, but you really wanted to, admit it.

So when do I use regular pointers then?
In code that is oblivious to pointer ownership. So, usually in functions which get a pointer from someplace else and don't allocate, de-allocate or store a copy of it which outlasts their execution.