Transferring the ownership of object from one unique_ptr to another unique_ptr in C++11?
Solution 1:
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
Solution 2:
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 .