Move Semantics and std::unique_ptr

How does std::unique_ptr utilize move semantics?

std::unique_ptr is a smart pointer that exclusively owns and manages the object it points to. When a unique_ptr is destroyed, the object it manages is automatically destroyed as well. A key feature of unique_ptr is that it cannot be copied, but it can be moved. This is where move semantics come into play.

Consider this example:

#include <iostream>
#include <memory>

class Resource {
public:
  Resource() {
    std::cout << "Resource acquired\n";
  }
  ~Resource() {
    std::cout << "Resource destroyed\n";
  }
};

int main() {
  std::unique_ptr<Resource> ResA{new Resource{}};
  std::unique_ptr<Resource> ResB{std::move(ResA)};  

  if (!ResA) {
    std::cout << "ResA is empty\n";
  }
}
Resource acquired
ResA is empty
Resource destroyed

Here, ResA initially manages a Resource object. When we move from ResA to ResB, ownership of the Resource is transferred to ResB. After the move, ResA is empty (it doesn't manage an object anymore), and ResB manages the Resource.

This is possible because unique_ptr has a move constructor and a move assignment operator. When you use std::move() on a unique_ptr, these move operations are invoked to transfer ownership of the managed object.

The move constructor of unique_ptr looks something like this:

unique_ptr(unique_ptr&& other) noexcept {
  ptr = other.ptr;
  other.ptr = nullptr;
}

It takes the pointer from other and sets other's pointer to nullptr. This efficiently transfers ownership without any copying.

The move semantics of unique_ptr are what allow it to be returned from functions and stored in containers like std::vector, enabling efficient and safe resource management.

It's worth noting that the use of std::move() with unique_ptr is not strictly necessary in many cases, as the compiler can infer that a move should happen in certain situations (like returning a local unique_ptr from a function). However, using std::move() can make the intention clearer and is necessary in some situations (like moving from a named unique_ptr as in the example above).

Move Semantics

Learn how we can improve the performance of our types using move constructors, move assignment operators and std::move()

Questions & Answers

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

When to Use Move Semantics
In what situations should I use move semantics instead of copy semantics?
Why Not Always Use Move Semantics
If move semantics are more efficient, why not always use them instead of copy semantics?
The Rule of Five
What is the Rule of Five in C++, and how does it relate to move semantics?
Noexcept Move Operations
What is the purpose of marking move operations as noexcept?
Move Semantics and Threads
How can move semantics be used to efficiently transfer resources between threads?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant