Channels ▼


3 Most Useful Library Features of C++0x

Smart Pointers

To use dynamic binding in C++, you must use pointers or references, because virtual functions work only in the context of a base-class pointer (or reference) that points (or refers) to a derived-class object.

However, neither pointers nor references do anything about memory allocation. As a result, C++ programmers who wish to use dynamic binding take on a memory-allocation burden that the language does nothing directly to solve.

The C++0x library adds three template classes that combine pointer-like behavior with automatic memory allocation in various ways: shared_ptr, unique_ptr, and weak_ptr. We expect that shared_ptr will be the most common; it is typically used this way:

class B { /* ... */ };
 class D: public B { /* ... */ };
 shared_ptr<B> pb(new D);

We have defined two classes related by inheritance. Now, we allocate a derived-class object, and instead of using a pointer variable to remember the pointer resulting from new, we use that pointer to initialize a shared_ptr<B>. From this point on, there is no need to use raw pointers directly.

From a user's viewpoint, a shared_ptr<B>' object is a value that acts like a pointer to an object of type B or of a type derived from B. You can copy shared_ptr objects freely; all copies refer to the same object. If pb is a shared_pointer<B> and mem is a member of B, you can refer to pb->mem as if pb were a pointer; if pb->mem is a virtual function, you can call it in the same way.

Where a shared_ptr differs from an ordinary pointer is that it keeps track of how many shared_ptr objects point to each individual object. When all of the shared_ptr objects pointing to a particular object go away, that object is destroyed too. Therefore, when you use new to allocate an object and give that object to a shared_ptr to manage, you don't have to worry about writing a delete to match your new.

Not having to worry about delete is a bigger deal than it seems at first. For example, it means that if you have a function that has a shared_ptr as a local variable, and there is no other copy of that shared_ptr, the object to which that shared_ptr refers will go away automatically when the function returns. Moreover, shared_ptrs behave this way even if the function returns due to an exception. In effect, shared_ptrs make exception-safe programs much easier to write.

They also make destructors unnecessary in many cases. If a class uses new in its constructors, all it has to do is use those calls to new to initialize shared_ptr data members; and the need for a delete in the destructor goes away. If that's all the destructor does — which is often the case — the whole destructor vanishes. Not only that, but without a user-defined destructor, a class can often do without a user-defined copy constructor or copy-assignment operator as well.

As a result, by using shared_ptr, class authors can often reduce the burden of writing four special member functions (constructor, destructor, copy constructor, and copy-assignment operator) to one (constructor). From a teaching viewpoint, using shared_ptr makes it possible to introduce constructors much earlier in the curriculum without having to introduce the other three special members until later.

In addition to shared_ptr, C++0x offers unique_ptr, which can be moved but not copied. This property means that only a single unique_ptr points to a given object at one time. If you can accept the no-copy restriction, unique_ptr runs more quickly than shared_ptr.

C++0x also offers weak_ptr, which is like shared_ptr except that it never deletes anything. Instead, when a weak_ptr points to the same object as a shared_ptr, and the last copy of the shared_ptr goes away (thereby deleting the object), the weak_ptr makes note of the deletion and lets you test later to see if this deletion has occurred. The main use of weak_ptr is to define circular data structures, which would otherwise never go away.

Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.