Smart Pointers and std::unique_ptr

Using std::unique_ptr as a Class Member

How do I use std::unique_ptr as a member of a class?

Illustration representing computer hardware

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:

  1. 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.
  2. 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.
  3. Access the managed resource through the unique_ptr member using  or >, just like you would with a normal pointer.
  4. Check if the unique_ptr member is managing a resource before trying to use it, as attempting to dereference an empty unique_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.

Answers to questions are automatically generated and may not have been reviewed.

Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved