In C++11
we can transfer the ownership of an object to another unique_ptr
using std::move()
. After the ownership transfer, the smart pointer that ceded the ownership becomes null
and get()
returns nullptr.
std::unique_ptr<int> p1(new int(42)); std::unique_ptr<int> p2 = std::move(p1); // Transfer ownership
What are the situations where this will be useful as it is transferring the ownership to another unique_ptr
?
A unique_ptr does not share its pointer. It cannot be copied to another unique_ptr , passed by value to a function, or used in any C++ Standard Library algorithm that requires copies to be made. A unique_ptr can only be moved.
An owner is an object containing a pointer to an object allocated by new for which a delete is required. Every object on the free store (heap, dynamic store) must have exactly one owner. If there are two pointers to an object on the free store, only one can be the owner.
The following situations involve transferring ownership from one unique_ptr
to another: returning from a function, and passing as a parameter to a function like a constructor.
Say you have some polymorphic type Animal
:
struct Animal { virtual ~Animal() {} virtual void speak() = 0; };
with concrete subclasses Cat
and Dog
:
struct Cat : Animal { void speak() override { std::cout << "Meow!\n"; } }; struct Dog : Animal { void speak() override { std::cout << "Woof!\n"; } };
And you want a simple factory that creates a pet based on a required value of obedience. Then the factory must return a pointer. We want the pet factory to transfer ownership of the created pet to the caller so a reasonable return type is std::unique_ptr<Animal>
:
std::unique_ptr<Animal> createPet(double obedience) { if (obedience > 5.0) return std::make_unique<Dog>(); return std::make_unique<Cat>(); }
Now, say we want to create a House
that will own the pet then we might want to pass the pet into the constructor of the House
. There is some debate (see comments on this blog post) about how best to pass a unique_ptr
to a constructor but it would look something like this:
class House { private: std::unique_ptr<Animal> pet_; public: House(std::unique_ptr<Animal> pet) : pet_(std::move(pet)) {} };
We have passed the unique_ptr
into the constructor and have then "moved" it to the member variable.
The calling code could look something like:
auto pet = createPet(6.0); House house(std::move(pet));
After constructing the House
, the pet
variable will be nullptr
because we have transferred ownership of the pet to the House
.
Live demo
for example if you call a function you can move
your unique_ptr
in the parameter list so it can be a part of your function signature
foo ( std::unique_ptr<T>&& ptr )
you can call foo with
foo( std::move(myPtr) );
Note that std::move
is an unconditional cast and unique_ptr
is an object with a state, and a part of that state is the pointer that that unique_ptr
is managing, with std::move
you are casting the entire object, you are not really changing anything about ownership, there is nothing peculiar about std::unique_ptr
while using std::move
because std::move
doesn't really care about anything specific, as I said it is an unconditional cast and unique_ptr
simply gets casted, the entire object that is an instance of type unique_ptr<T>
is casted .
If you want to talk about a transfer of ownership of the object pointed by your unique_ptr
, you should consider the swap
provided by std::unique_ptr<T>
itself .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With