Several smart pointer classes were added in C++11 for managing dynamically allocated memory. By using these container classes, instead of raw pointers, it is no longer necessary to manually delete objects created with the new keyword. This simplifies coding by helping to prevent memory leaks.
Unique Pointer
The first smart pointer that we look at is the unique pointer (std::unique_ptr), which simply acts as a container for a raw pointer. It replaces another deprecated smart pointer named auto_ptr, which was removed in C++17. Consider the following example on how to use a unique pointer.
The output of this code is "123" as the pointer is created, used, and then destroyed automatically when it goes out of scope. Note that the smart pointer is created not through assignment but instead by passing a raw pointer to its constructor. Once created, however, the smart pointer is used just as a regular pointer, in this case with the arrow operator (->) to dereference the pointer and access the member of the object in a single operation.
As the name implies, a unique pointer has exclusive ownership of the object it points to and therefore cannot be copied. It can, however, transfer ownership to another unique pointer using the std::move function. After completing such a transfer, the original pointer will be set to nullptr.
Shared Pointer
In cases where shared ownership of a dynamically allocated object is necessary, there is the shared pointer (std::shared_ptr). Unlike the unique pointer, a shared pointer can be copied. The memory to the object will not be deallocated until the last remaining shared pointer owning the object is destroyed, either by going out of scope or by resetting the pointer to nullptr manually.
As of C++14, use of the new keyword is discouraged in most circumstances. Instead, the std::make_unique and std::make_shared functions are recommended when allocating dynamic memory .
Weak Shared Pointer
A weak shared pointer (std::weak_ptr) can be created from a shared pointer. Unlike the shared pointer, a weak shared pointer is non-owning, meaning that the object will be cleaned up when all shared pointers go out of scope, regardless of any weak shared pointers. In order to access the referenced object, a weak shared pointer must first be converted into a shared pointer using the lock method. Here is an example to illustrate.