c++boost.gif (8819 bytes)Smart Pointers

Smart pointers are classes which store pointers to dynamically allocated (heap) objects.  They behave much like built-in C++ pointers except that they automatically delete the object pointed to at the appropriate time. Smart pointers are particularly useful in the face of exceptions as they ensure proper destruction of dynamically allocated objects. They can also be used to keep track of dynamically allocated objects shared by multiple owners.

Conceptually, smart pointers are seen as owning the object pointed to, and thus responsible for deletion of the object when it is no longer needed.

The header boost/smart_ptr.hpp provides four smart pointer template classes:

scoped_ptr

Simple sole ownership of single objects.
scoped_array Simple sole ownership of arrays.
shared_ptr Object ownership shared among multiple pointers
shared_array Array ownership shared among multiple pointers.

These classes are designed to complement the C++ Standard Library auto_ptr class.

They are examples of the "resource acquisition is initialization" idiom described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition, Section 14.4, Resource Management.

A test program (smart_ptr_test.cpp) is provided to verify correct operation.

A page on Smart Pointer Timings will be of interest to those curious about performance issues.

Common requirements

These smart pointer classes have a template parameter, T, which specifies the type of the object pointed to by the smart pointer.  The behavior of all four classes is undefined if the destructor or operator delete for objects of type T throws exceptions.

Exception safety

Several functions in these smart pointer classes are specified as having "no effect" or "no effect except such-and-such" if an exception is thrown.   This means that when an exception is thrown by an object of one of these classes, the entire program state remains the same as it was prior to the function call which resulted in the exception being thrown.  This amounts to a guarantee that there are no detectable side effects.   Other functions never throw exceptions. The only exception ever thrown by functions which do throw (assuming T meets the Common requirements)  is std::bad_alloc, and that is thrown only by functions which are explicitly documented as possibly throwing std::bad_alloc.

Exception-specifications

Exception-specifications are not used; see exception-specification rationale.

All four classes contain member functions which can never throw exceptions, because they neither throw exceptions themselves nor call other functions which may throw exceptions.  These members are indicated by a comment: // never throws.

Functions which destroy objects of the pointed to type are prohibited from throwing exceptions by the Common requirements.

History and acknowledgements

November, 1999. Darin Adler provided operator ==, operator !=, and std::swap and std::less specializations for shared types.

September, 1999. Luis Coelho provided shared_ptr::swap and shared_array::swap

May, 1999.  In April and May, 1999, Valentin Bonnard and David Abrahams made a number of suggestions resulting in numerous improvements.  See the revision history in smart_ptr.hpp for the specific changes made as a result of their constructive criticism.

Oct, 1998.  In 1994 Greg Colvin proposed to the C++ Standards Committee classes named auto_ptr and counted_ptr which were very similar to what we now call scoped_ptr and shared_ptr.  The committee document was 94-168/N0555, Exception Safe Smart Pointers.  In one of the very few cases where the Library Working Group's recommendations were not followed by the full committee, counted_ptr was rejected and surprising transfer-of-ownership semantics were added to auto-ptr.

Beman Dawes proposed reviving the original semantics under the names safe_ptr and counted_ptr at an October, 1998, meeting of Per Andersson, Matt Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar Kühl, Nathan Myers, Chichiang Wan and Judy Ward.  During the discussion, the four class names were finalized, it was decided that there was no need to exactly follow the std::auto_ptr interface, and various function signatures and semantics were finalized.

Over the next three months, several implementations were considered for shared_ptr, and discussed on the boost.org mailing list.  The implementation questions revolved around the reference count which must be kept, either attached to the pointed to object, or detached elsewhere. Each of those variants have themselves two major variants:

Each implementation technique has advantages and disadvantages.  We went so far as to run various timings of the direct and indirect approaches, and found that at least on Intel Pentium chips there was very little measurable difference.  Kevlin Henney provided a paper he wrote on "Counted Body Techniques."  Dietmar Kühl suggested an elegant partial template specialization technique to allow users to choose which implementation they preferred, and that was also experimented with.

But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage users", and in the end we choose to supply only the direct implementation.

See the Revision History section of the header for further contributors.


Revised  27 Jul 2000

© Copyright Greg Colvin and Beman Dawes 1999. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.