Smart pointers are class templates that manage a resource (typically a heap-allocated object) and ensure its destruction when the pointer goes out of scope. They are defined in the <memory> header.
1. std::unique_ptr (C++11)
A unique_ptr owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope. Ownership is exclusive — it cannot be copied, only moved.
std::unique_ptr<int> p1 = std::make_unique<int>(10);
// std::unique_ptr<int> p2 = p1; // COMPILE ERROR: Cannot copy
std::unique_ptr<int> p2 = std::move(p1); // OK: p1 is now null
2. std::shared_ptr (C++11)
Implements shared ownership. Multiple shared_pointers can point to the same object. The object is destroyed when the last shared_ptr is destroyed or reset. It uses a control block for reference counting.
auto sp1 = std::make_shared<MyClass>();
{
auto sp2 = sp1; // Reference count increases to 2
std::cout << sp1.use_count(); // Prints 2
} // sp2 destroyed, count becomes 1
Pro-tip: Always use std::make_shared. It performs a single memory allocation for both the object and the control block, improving cache locality and reducing overhead.
3. std::weak_ptr (C++11)
A "weak" reference that doesn't affect the reference count. It is used to break circular dependencies between shared_ptr instances. You must call lock() to convert it back to a shared_ptr before use.