Smart Pointers and std::unique_ptr

Using Smart Pointers with Custom Deleters

Can I use smart pointers with my own custom deleters?

Illustration representing computer hardware

Yes, std::unique_ptr allows you to specify a custom deleter. This can be useful if you need to do something more than just call delete when the pointer is destroyed.

Here's an example where we use a custom deleter to print a message when the object is destroyed:

#include <memory>
#include <iostream>

class Character {
public:
  std::string Name;
  Character(std::string Name) : Name{Name} {
    std::cout << "Creating " << Name << '\n';
  }
  ~Character() {
    std::cout << "Destroying " << Name << '\n';
  }
};

struct CharacterDeleter {
  void operator()(Character* c) const {
    std::cout << "Custom deleting "
      << c->Name << '\n';
    delete c;
  }
};

int main() {
  std::unique_ptr<Character, CharacterDeleter>
    Gandalf{new Character{"Gandalf"}};
}
Creating Gandalf
Custom deleting Gandalf
Destroying Gandalf

Here, we define a CharacterDeleter struct that overloads the () operator. This operator will be called when the unique_ptr needs to delete the Character.

We then specify CharacterDeleter as the second template argument to std::unique_ptr. This tells the unique_ptr to use CharacterDeleter instead of the default deleter.

You can also use a lambda as a custom deleter:

#include <memory>
#include <iostream>

class Character {
public:
  std::string Name;
  Character(std::string Name) : Name{Name} {
    std::cout << "Creating " << Name << '\n';
  }
  ~Character() {
    std::cout << "Destroying " << Name << '\n';
  }
};

int main() {
  std::unique_ptr<Character,
    void(*)(Character*)> Gandalf{
    new Character{"Gandalf"},
    [](Character* c) {
      std::cout << "Custom deleting "
        << c->Name << '\n';
      delete c;
    }
  };
}
Creating Gandalf
Custom deleting Gandalf
Destroying Gandalf

Here, we specify the type of the deleter as void(*)(Character*), which is a function pointer that takes a Character* and returns void. We then pass a lambda with this signature as the second argument to the unique_ptr constructor.

Custom deleters can be useful for managing resources that aren't directly heap-allocated with new, such as file handles, network sockets, or graphics resources.

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