Using std::move with std::unique_ptr
What does std::move do when used with std::unique_ptr?
std::move, defined in the <utility> header, is used to indicate that an object t may be "moved from", i.e., allowing the efficient transfer of resources from t to another object.
In the context of std::unique_ptr, std::move is used to transfer ownership of the managed resource from one unique_ptr to another.
Consider this example:
#include <memory>
#include <utility>
#include <iostream>
int main() {
std::unique_ptr<int> p1{
std::make_unique<int>(42)};
std::cout << *p1 << '\n';
std::unique_ptr<int> p2{std::move(p1)};
std::cout << *p2 << '\n'
<< (p1 ? "p1 is not null" : "p1 is null");
}42
42
p1 is nullHere, p1 initially manages an int with the value 42. We then use std::move to transfer ownership of this int to p2. After the move, p2 manages the int, and p1 is set to nullptr.
This move operation is efficient because it just transfers the pointer from p1 to p2. No deep copy of the managed int is made.
std::move is often used when passing a unique_ptr to a function that takes ownership of the managed resource:
#include <memory>
#include <utility>
#include <iostream>
void TakeOwnership(std::unique_ptr<int> p) {
if (p) {
std::cout << "Taking ownership of " << *p;
}
}
int main() {
std::unique_ptr<int> p{
std::make_unique<int>(42)};
TakeOwnership(std::move(p));
}Taking ownership of 42Here, std::move is used to transfer ownership of the int managed by p to the p parameter of TakeOwnership.
It's important to note that after a unique_ptr has been moved from, it no longer manages a resource. Attempting to use a unique_ptr after it has been moved from leads to undefined behavior:
#include <iostream>
#include <memory>
#include <utility>
int main() {
std::unique_ptr<int> p1{
std::make_unique<int>(42)};
std::unique_ptr<int> p2{
std::move(p1)};
std::cout << *p1; // undefined behavior!
}Therefore, it's crucial to be aware of when a unique_ptr has been moved from and to not use it afterwards.
In summary, std::move with std::unique_ptr is used to efficiently transfer ownership of a managed resource from one unique_ptr to another, leaving the original unique_ptr in a state where it no longer manages a resource.
Smart Pointers and std::unique_ptr
An introduction to memory ownership using smart pointers and std::unique_ptr in C++