Table of Contents
unique_ptr
std::unique_ptr is a smart pointer that owns a heap-allocated object exclusively: exactly one unique_ptr points at a given object at any time, and when that unique_ptr is destroyed, moved-from, or reset, the object is destroyed with it. It's the default choice for owning a heap allocation in modern C++, since it has zero overhead over a raw pointer (no reference count, no atomic operations) and makes ownership explicit in the type itself.
std::unique_ptr<Widget> make_widget() { return std::make_unique<Widget>(); // ownership starts here } void use() { auto w = make_widget(); // w now owns the Widget w->doThing(); } // Widget destroyed automatically when w goes out of scope
Move-only, not copyable
unique_ptr's copy constructor and copy assignment operator are deleted; only moving is allowed. This is the whole point: if unique_ptr could be copied, two objects would think they exclusively own the same pointer, and both destructors would eventually run delete on it, a double free. Moving transfers ownership instead of duplicating it, leaving the moved-from unique_ptr null.
std::unique_ptr<Widget> a = std::make_unique<Widget>(); std::unique_ptr<Widget> b = std::move(a); // ownership moves to b // a is now null; using a->doThing() here is undefined behavior
This is also exactly why a function that only needs to use an object, not own it, should take a raw pointer or reference rather than a unique_ptr parameter: taking unique_ptr by value forces the caller to give up ownership (or copy-construct, which won't compile), which is rarely what's intended.
Custom deleters and arrays
The second template parameter is the deleter type, which defaults to calling delete. A custom deleter lets unique_ptr manage non-memory resources through the same RAII mechanism, a FILE* closed with fclose, for instance, instead of freed with delete.
auto file = std::unique_ptr<FILE, decltype(&fclose)>( fopen("data.txt", "r"), &fclose); // fclose(file.get()) runs automatically when file goes out of scope
unique_ptr<T[]> is a separate specialization for arrays; it calls delete[] instead of delete and provides operator[] instead of operator*/operator->. Mixing them up, using plain unique_ptr<T> for an array, calls the wrong delete form and is undefined behavior.
