Pageviews

Wednesday, July 22, 2015

unique_ptr vs shared_ptr (weak_ptr) vs auto_ptr

unique_ptr

In C++, a smart pointer is implemented as a template class that mimics, by means of operator overloading, the behaviors of a traditional (raw) pointer, (e.g. dereferencing, assignment) while providing additional memory management features.
Smart pointers can facilitate intentional programming by expressing in the type itself how the memory of the referent of the pointer will be managed. For example, if a C++ function returns a pointer, there is no way to know whether the caller should delete the memory of the referent when the caller is finished with the information.
some_type* ambiguous_function(); // What should be done with the result?
Traditionally, comments have been used to resolve the ambiguity[citation needed], which is an error-prone, labor-intensive approach. C++11 introduced a way to ensure correct memory management in this case by declaring the function to return a unique_ptr,
unique_ptr<some_type> obvious_function1();
The declaration of the function return type as a unique_ptr makes explicit the fact that the caller takes ownership of the result, and the C++ runtime ensures that the memory for *some_type will be reclaimed automatically. Prior toC++11, unique_ptr can be replaced with auto_ptr.
Example: unique_ptr can only be transferred not copied.
std::unique_ptr<int> p1(new int(5));
std::unique_ptr<int> p2 = p1; //Compile error.
std::unique_ptr<int> p3 = std::move(p1); //Transfers ownership. p3 now owns the memory and p1 is rendered invalid.

p3.reset(); //Deletes the memory.
p1.reset(); //Does nothing.

shared_ptr (weak_ptr)
shared_ptr is a container for a raw pointer. It maintains reference-counted ownership of its contained pointer in cooperation with all copies of the shared_ptr. The object referenced by the contained raw pointer will be destroyed when and only when all copies of the shared_ptr have been destroyed.
std::shared_ptr<int> p1(new int(5));
std::shared_ptr<int> p2 = p1; //Both now own the memory.

p1.reset(); //Memory still exists, due to p2.
p2.reset(); //Deletes the memory, since no one else owns the memory.
weak_ptr is a container for a raw pointer. It is created as a copy of a shared_ptr. The existence or destruction of weak_ptr copies of a shared_ptr have no effect on the shared_ptr or its other copies. After all copies of a shared_ptr have been destroyed, all weak_ptr copies become empty.
Because the implementation of shared_ptr uses reference countingcircular references are potentially a problem. A circular shared_ptr chain can be broken by changing the code so that one of the references is aweak_ptr.
Multiple threads can safely simultaneously access different shared_ptr and weak_ptr objects that point to the same object.[4]
The referenced object itself needs to be protected separately to ensure thread safety.

auto_ptr 
Create new objects using auto_ptr to ease the allocation of a
std::shared_ptr<some_type>
C++11 introduced:
 auto s = std::make_shared<some_type>(constructor, parameters, here);
and similarly
std::unique_ptr<some_type>
Since C++14 one can use:
 auto u = std::make_unique<some_type>(constructor, parameters, here);
It is preferred, in almost all circumstances, to use these facilities over the new keyword:[1]