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
ResourceHandlerinstances. - 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.,
sizeis 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++