I do not fully understand the benefits of unique_ptr
over auto_ptr
, or I am not yet fully convinced why we need to use unique_ptr
.
I see the following differences.
1) unique_ptr
supports arrays and thus the unique_ptr
destructor calls delete []
for arrays whereas the auto_ptr
destructor calls only delete
.
2) std::move()
has to be used instead of directly copying in case of unique_ptr
. But what advantage do we get with std::move()
? I will try to explain as below.
auto_ptr <int> p1 (new int);
auto_ptr <int> p2 = p1; // Now p1 is NULL and p2 exists with value of p1
unique_ptr <int> p1 (new int);
unique_ptr <int> p2 = std::move(p1); // Now p1 is NULL and p2 exists with value of p1
so what is the advantage we are going to get with this?
3) I read on the Internet that unique_ptr
can be used in containers. But if I understood correctly, this is not the great thing of unique_ptr
. Container function semantics are changed so now a days, copying is not getting done inside of the container functions. But how is this the great thing of unique_ptr
? Now that container functions are changed, why we cannot use auto_ptr
in containers?
First of all, auto_ptr
has/had magic constructors, like auto_ptr(auto_ptr &other) {...}
, which would behave like:
other
instance.other
instance.Nowadays compilers support std::move(...)
, hence no need for "copy-style" constructor that did in reality "move", but to support old code, auto_ptr
was left unchanged, and instead got deprecated (to be removed later).
unique_ptr
forces you to be explicit about transferring ownership, so it is visible and clear in the code. With auto_ptr
it is too easy to get silent transfers of ownership and when reading the code it's not always clear whether ownership is transferred, and if it is, whether it was intended by the author of the code or is a bug! When you see a unique_ptr
used with std::move
it is obvious that the intention is to transfer ownership.
unique_ptr
properly supports move semantics, so it only allows ownership transfer from temporaries and moved objects (i.e. rvalues). Containers can detect if a type is "move aware" and act appropriately. auto_ptr
does not know about move semantics, and will transfer ownership from lvalues or rvalues, so containers think it's a normal copyable object, but it doesn't behave like one because it modifies its source when copying.
auto_ptr
was useful when used carefully, but it was too easy to misuse it and write dangerous code. It is time for it to die. unique_ptr
supports everything auto_ptr
can do, but is safe by default (you have to try harder to use it wrong) and also has extra features like custom deleters and array support.