C++ Core
Smart Pointers
RAII wrappers that own a heap object and delete it automatically.
Concept core idea Watch out easy to get wrong
Concept
Key concepts
- Smart pointers (in
<memory>) are RAII wrappers around a raw pointer: they own the heap object and auto-deleteit when they go out of scope — no manual delete, leaks, or dangling. unique_ptr= sole owner; can't be copied, only moved (std::move); near-zero overhead. Your default. Create withmake_unique.shared_ptr= shared ownership via a reference count; the object is deleted when the count hits 0 (use_count()). Create withmake_shared(one allocation). Has a control-block overhead.weak_ptr= non-owning observer of ashared_ptr; does NOT change the count. Used to break circular references and to check/access via.lock()(or.expired()). (Deep dive: the shared_ptr circular reference page linked at the bottom of this lesson.)- Prefer
make_unique/make_sharedover rawnew(exception-safe, no rawnew). Smart pointers overload*and->, so you use them like raw pointers. - Members:
.get()(raw pointer — don't delete),.reset()(delete now),unique_ptr::release()(give up ownership WITHOUT deleting — you must delete). Use raw pointers/references only for non-owning borrowing.
Creating, moving, sharing, observing
#include <memory>
auto u = std::make_unique<Entity>(); // sole owner
auto v = std::move(u); // ownership moved; u is now nullptr
auto s = std::make_shared<Entity>(); // use_count() == 1
auto s2 = s; // use_count() == 2 (shared)
std::weak_ptr<Entity> w = s; // observes, does NOT bump the count
if (auto sp = w.lock()) { /* alive -> use sp */ }
v->method(); // smart pointers use -> and * like raw pointers Deep dive
Go deeper
Watch out
Easily confused
unique_ptr vs shared_ptr
unique = one owner, move-only, no overhead. shared = many owners, ref-counted, deleted at count 0 (has a control block).
weak_ptr vs shared_ptr
shared owns and counts. weak observes without counting — breaks cycles; use
.lock() to access safely.release() vs reset() vs move
release() = give up ownership, NO delete (you must delete). reset() = delete now. move = transfer to another smart pointer.
owning vs non-owning
Smart pointers express ownership. Raw pointers/references are for borrowing — never delete through them.
Test yourself
8 questions on this lesson. Write your answers from memory, then compare them with the model answers side by side.