The unique_ptr or unique pointer, is considered a smart pointer. The reason it is called unique is because this type of object holds sole ownership of its pointer. This means that no two unique_ptr pointers can manage the same object, it is unique. One of the biggest advantages of unique_ptr is that it manages its own lifetime. What this means is that when the pointer goes out of scope, it automatically destroys itself and deallocates its memory. This solves the dreaded dangling pointer issues and avoids memory leaks. This also removes the issue of ownership since now it is explicit who deletes the pointer.
Since the C++14 standard, we can now use a handy little function to create a unique pointer, make_unique. The make_unique function creates an object of type T and then wraps it in a unique pointer. The syntax for creating the unique_ptr pointer with make_unique would look something like the following:
std::unique_ptr<T> p = new std::make_unique<T>();
Once created, you can use the pointer much like a classic pointer. The dereference operators, * and ->, work just like they normally would. Again the big difference here is that the pointer is automatically destroyed when it goes out of scope, freeing us from having to track every exit point manually to avoid any memory leak issues.
The shared_ptr or shared pointer is a lot like the unique pointer. It is considered a smart pointer, it handles deletion and deallocation of memory automatically. The difference is that the shared pointer shares ownership of the object. This means that, unlike the unique pointer, a shared pointer can be one of many shared pointers, pointing to a single object. This means that if a shared pointer goes out of scope or is pointed to another object, through reset() or the = operator, the object still remains. It is only destroyed and its memory deallocated when all the shared_ptr objects owning the object are either destroyed, go out of scope, or are reassigned to another pointer.
Again, like the unique pointer, the shared pointer also has a handy function for creation. The make_shared function creates an object of type T and then wraps it in a shared pointer. The syntax for creating the shared_ptr function using the make_shared function would look like the following:
std::shared_ptr<T> p = new std::make_shared<T>();
Also, like the unique pointer, the shared pointer has the typical dereference operators, * and ->.