Managing Resources with std::unique_ptr

How can you effectively use std::unique_ptr to manage resources in a class that also needs to support copying and assignment?

std::unique_ptr is designed for exclusive ownership of a resource, which complicates its use in classes that need to support copying and assignment, as std::unique_ptr itself is not copyable.

Solution: Disable Copying

To manage resources with std::unique_ptr in a class that needs to support copying and assignment, you should disable copying and provide custom implementations for copy construction and assignment.

Example

Consider a class ResourceHandler that manages a dynamic array with std::unique_ptr:

#include <iostream>
#include <memory>

class ResourceHandler {
public:
  ResourceHandler(size_t size)
    : data(std::make_unique<int[]>(size)),
      size(size) {}

  // Disable copy construction and assignment
  ResourceHandler(const ResourceHandler&)
    = delete; 
  ResourceHandler& operator=(
    const ResourceHandler&) = delete; 

  // Provide move constructor and assignment
  ResourceHandler(
    ResourceHandler&& other) noexcept
    : data(std::move(other.data)),
      size(other.size) {
    other.size = 0; 
  }

  ResourceHandler& operator=(
    ResourceHandler&& other) noexcept {
    if (this != &other) {
      data = std::move(other.data);
      size = other.size;
      other.size = 0; 
    }
    return *this;
  }

  void Print() const {
    for (size_t i = 0; i < size; ++i) {
      std::cout << data[i] << ' ';
    }
    std::cout << '\n';
  }

private:
  std::unique_ptr<int[]> data;
  size_t size;
};

Explanation

  • Copy Construction and Assignment Disabled: By deleting the copy constructor and assignment operator, you prevent copying of ResourceHandler instances.
  • Move Semantics: The move constructor and move assignment operator transfer ownership of the resource. The moved-from object is left in a valid but unspecified state (e.g., size is set to 0).

This approach ensures that each ResourceHandler instance has exclusive ownership of its resource and avoids problems related to copying.

Managing Memory Manually

Learn the techniques and pitfalls of manual memory management 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.

Avoiding Raw Pointers
Why should we avoid using raw pointers when possible in modern C++ programming?
Smart Pointer Pitfalls
What are some common pitfalls when using the get() method with smart pointers, and how can they be avoided?
Using reset() vs Assignment
When should you use reset() method on smart pointers versus directly assigning a new smart pointer?
Custom Deleters with std::unique_ptr
What role does the custom deleter in std::unique_ptr play, and when would you need to use it?
Custom Deleters in Smart Pointers
Can you provide an example of using a custom deleter with a std::unique_ptr and explain its use?
Detecting Memory Leaks in Complex Applications
What are some strategies for detecting memory leaks in a large, complex application?
Rule of Three and std::unique_ptr
How does the Rule of Three apply when using std::unique_ptr for resource management?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant