Logo

Blog


Understanding the inner workings of C++ smart pointers - The unique_ptr

Have you always wondered how the two smart pointers unique_ptr and shared_ptr work internally? Then, this series might give you a better understanding.

This article is the first part of a series around smart pointers. The goal is to give you a better understanding of the internals of the smart pointers as well as show you some implementation techniques the Standard Library uses that could be transferable to your work.

A minimalistic unique_ptr implementation

As you probably know, the unique_ptr is the cheapest of the two smart pointers. You get a small wrapper around a raw pointer that ensures memory safety. Below, you find a minimalistic implementation of a unique_ptr.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
template<typename T>
class unique_ptr {
  T* mPtr{};

public:
  unique_ptr() = default;

  unique_ptr(T* ptr)
  : mPtr{ptr}
  {}

  unique_ptr(const unique_ptr&)           = delete;
  unique_ptr operator=(const unique_ptr&) = delete;

  unique_ptr(unique_ptr&& src)
  : mPtr{src.mPtr}
  {
    src.mPtr = nullptr;
  }

  unique_ptr& operator=(unique_ptr&& src)
  {
    delete mPtr;
    mPtr     = src.mPtr;
    src.mPtr = nullptr;

    return *this;
  }

  ~unique_ptr()
  {
    static_assert(sizeof(T) >= 0, "cannot delete an incomplete type");
    delete mPtr;
  }

  T* operator->() { return mPtr; }
};

No surprise, unique_ptr is a class template. I simplified it even further. The regular unique_ptr has a second type template parameter for a custom deleter. Let's ignore that detail.

Internally, unique_ptr stores a raw pointer of T. The class has a default constructor, while the copy operations are deleted. The move operations are implemented to swap the pointer while first deleting existing data, in the case of the move assignment operator.

Then there is the destructor, responsible for deleting the memory on destruction. Last, with get, you see the access function for accessing the data.

There are more things in the STL implementations, but this is essentially what you need.

More to come

Next time, I will show you how the implementation changes if you add the custom deleter to the picture.

Andreas