# 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. ```cpp std::unique_ptr make_widget() { return std::make_unique(); // 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. ```cpp std::unique_ptr a = std::make_unique(); std::unique_ptr 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`. ```cpp auto file = std::unique_ptr( fopen("data.txt", "r"), &fclose); // fclose(file.get()) runs automatically when file goes out of scope ``` `unique_ptr` 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` for an array, calls the wrong delete form and is undefined behavior. ## Links - https://en.cppreference.com/w/cpp/memory/unique_ptr.html