Using std::unique_ptr
as a Class Member
How do I use std::unique_ptr
as a member of a class?
Using std::unique_ptr
as a member of a class is a way to ensure that the class manages the lifetime of the pointed-to resource. When the class instance is destroyed, the unique_ptr
member will automatically clean up the resource it manages.
Here's an example of a class Wizard
that has a unique_ptr
member which manages a Wand
resource:
#include <memory>
#include <iostream>
class Wand {
public:
Wand() { std::cout << "Wand created.\n"; }
~Wand() { std::cout << "Wand destroyed.\n"; }
};
class Wizard {
private:
std::unique_ptr<Wand> wand_;
public:
Wizard() : wand_{std::make_unique<Wand>()} {}
void CastSpell() {
if (wand_) {
std::cout << "Casting spell!\n";
} else {
std::cout << "I have no wand!\n";
}
}
};
int main() {
Wizard gandalf;
gandalf.CastSpell();
}
Wand created.
Casting spell!
Wand destroyed.
In this example, the Wizard
class has a unique_ptr<Wand>
member. When a Wizard
instance is created, it creates a new Wand
instance and stores it in the unique_ptr
member.
When the Wizard
instance goes out of scope (in this case, at the end of main
), the Wizard
destructor is called. Although we haven't explicitly defined a destructor for Wizard
, the compiler provides a default destructor that will call the destructors of all the class's members - including the destructor of wand_
, which in turn will delete the Wand
instance.
This pattern of using unique_ptr
as a class member is useful for implementing composition relationships, where one class is responsible for the lifetime of instances of another class.
Some key points to remember when using unique_ptr
as a class member:
- If you define a custom destructor for your class, you don't need to explicitly delete the
unique_ptr
member - it will clean up its managed resource automatically. - If you define custom copy/move constructors or copy/move assignment operators for your class, you need to decide how you want to handle the
unique_ptr
member. Often, it makes sense to prohibit copying and only allow moving, which can be achieved by deleting the copy constructor and copy assignment operator. - Access the managed resource through the
unique_ptr
member using or>
, just like you would with a normal pointer. - Check if the
unique_ptr
member is managing a resource before trying to use it, as attempting to dereference an emptyunique_ptr
will cause undefined behavior.
Using unique_ptr
as a class member is a key part of implementing RAII (Resource Acquisition Is Initialization) in C++, which is a powerful technique for managing resources and avoiding leaks.
Smart Pointers and std::unique_ptr
An introduction to memory ownership using smart pointers and std::unique_ptr
in C++