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