Smart pointers are a software construct which relates to pointer variables/objects which have added functionality over the concept of a raw pointer, which is just a single variable which stores an address in memory.
Problems With Raw Pointers
- It’s declaration doesn’t indicate whether it points to a single object or array. This also means than when it comes to deleting it, you don’t know whether to use delete or delete.
- It doesn’t tell you anything about whether you should delete what it points to once you have finished using it (it doesn’t tell you whether the pointer owns the thing it points to).
- It’s difficult to delete a pointer once an only once only all paths of execution in you code.
- There is no way to tell if a pointer dangles, and it can be prudent to also check to make sure the pointer is non-null (typically when a pointer is non-initialised, or been deleted and then set to null) before attempting to use it.
C++ std Library To The Rescue
Fortunately, the C++ standard library ( std) provides a range of smart pointers to overcome these problems with raw pointers.
std::unique_ptr is your bread and butter when it comes to smart pointers. A unique_ptr enforces exclusive ownership. One and only one pointer may own the memory at one time, and no other pointers may point to that memory. For that reason, you cannot copy a unique_ptr (copying would result in two unique_ptr’s pointers pointing to the same memory), but you may move it.
Moving a unique_ptr moves ownership of the memory from the source pointer to the destination pointer. After a move, the source pointer is automatically set to null.
Upon destruction of a unique_ptr (let’s say the pointer goes out of scope), the pointer also destroys the memory it points to. By default, unique_ptr’s destroy the memory by calling delete, but, during construction, they can be assigned custom deleters. Custom deleters are user-defined functions (or function objects, if using lambda expressions) that are automatically called by unique_ptr when it is time for the memory to be destroyed.
Because of the limited abilities of a unique_ptr, it does not add much overhead or size compared to a raw pointer. It is small and light-weight.