Skip to main content

Smart Pointers Overview

Boost.SmartPtr is where modern C++ ownership semantics were invented. Long before std::shared_ptr and std::unique_ptr existed, Boost shipped a family of pointer-like class templates that tie a raw pointer's lifetime to an object's scope, so memory and other resources are released automatically and exception-safely. Most of the family was later folded into the standard library — but Boost still offers a few members std never adopted.

The whole family at a glance

shared_ptr, weak_ptr, scoped_ptr, intrusive_ptr, plus the array cousins scoped_array and shared_array. Each encodes a different ownership policy — who owns the object, how many owners there can be, and where the bookkeeping lives.

Ownership models

The single most important question a smart pointer answers is who owns this object. Boost's pointers each pick a different answer:

PointerOwnershipCopyableOverheadstd equivalent
scoped_ptrSingle, non-transferableNoNone (just a pointer)unique_ptr (movable)
shared_ptrShared, reference-countedYesSeparate control blockstd::shared_ptr
weak_ptrNon-owning observerYesShares control blockstd::weak_ptr
intrusive_ptrShared, count inside objectYesOne pointer, no blocknone
scoped_array / shared_arrayAs above, for T[]unique_ptr<T[]> / shared_ptr<T[]>

Choosing one

  • One owner, lifetime bound to a scope — reach for scoped_ptr, or in modern code std::unique_ptr (which adds move semantics). See Boost and the standard.
  • Shared ownershipshared_ptr is the default; use weak_ptr to break reference cycles and observe without owning.
  • Shared ownership where size or an existing refcount mattersintrusive_ptr stores the count inside the object, so the pointer is a single machine word with no separate allocation.
Prefer std when you can

Since C++11 the standard versions cover the common cases and integrate with the rest of std. Reach for the Boost versions when you need something they add — intrusive_ptr (no std analogue), or when you must support a pre-C++11 toolchain.

Why smart pointers at all

The underlying idea is RAII: the pointer is an object whose destructor releases the resource, so cleanup happens on every exit path — normal return, early return, or a thrown exception — without a single explicit delete. This is the same principle that underpins the rest of Boost's resource-owning types, from Boost.Pool allocators to file handles.

See also