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 null

Here, 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 42

Here, 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++

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Mixing Smart and Raw Pointers
Is it okay to mix smart pointers and raw pointers in the same program?
Should I Pass Smart Pointers by Reference?
Should I pass smart pointers by value or reference?
Dynamically Allocating Arrays with Smart Pointers
How do I dynamically allocate an array with smart pointers?
Using Smart Pointers with Custom Deleters
Can I use smart pointers with my own custom deleters?
std::make_unique vs new Keyword
What are the advantages of using std::make_unique over the new keyword?
Using std::unique_ptr as a Class Member
How do I use std::unique_ptr as a member of a class?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant