std::unique_ptr
: a Smart Pointer that Cannot be Copied
A std::unique_ptr
owns of the object it points to and no other smart pointers can point to it. When the std::unique_ptr
goes out of scope, the object is deleted. This is useful when you are working with a temporary, dynamically-allocated resource that can get destroyed once out of scope.
How to construct a std::unique_ptr
A std::unique_ptr
is created like this:
std::unique_ptr<Type> p(new Type);
For example:
std::unique_ptr<int> p1(new int); std::unique_ptr<int[]> p2(new int[50]); std::unique_ptr<Object> p3(new Object("Lamp"));
It is also possible to construct std::unique_ptr
s with the help of the special function std::make_unique...
std::make_unique<>()
Use std::make_unique<>()
to create a unique_ptr. For example, instead of writing the following:
Employee* anEmployee = new Employee;
You should write:
auto anEmployee = std::make_unique<Employee>();
If your compiler is not yet C++14 compliant you can make your unique_ptr
as follows. Note that you now have to specify the type, Employee
, twice:
std::unique_ptr<Employee> anEmployee(new Employee);
You can now use the anEmployee smart pointer the same way as a normal pointer.
Some more examples:
std::unique_ptr<int> p1 = std::make_unique<int>(); std::unique_ptr<int[]> p2 = std::make_unique<int[]>(50); std::unique_ptr<Object> p3 = std::make_unique<Object>("Lamp");
Note: If you can, always choose to allocate objects using std::make_unique
.
One resource, one std::unique_ptr
I could say that std::unique_ptr
is very jealous of the dynamic object it holds: you can't have multiple references to its dynamic data. For example:
void compute(std::unique_ptr<int[]> p) { ... } int main() { std::unique_ptr<int[]> ptr = std::make_unique<int[]>(1024); std::unique_ptr<int[]> ptr_copy = ptr; // ERROR! Copy is not allowed compute(ptr); // ERROR! `ptr` is passed by copy, and copy is not allowed }
This is done on purpose and it's an important feature of std::unique_ptr
: there can be at most one std::unique_ptr
pointing at any one resource. This prevents the pointer from being incorrectly deleted multiple times.
Technically this happens because a std::unique_ptr
doesn't have a copy constructor: it might be obvious to you if you are familiar with move semantics.