smart pointer in C++

C++ has three smart pointers, 
* std::unique_ptr: A unique_ptr does not share its pointer. It cannot be copied or passed by value to a function. A unique_ptr can only be moved, which means that the ownership of the memory resource is transferred to another unique_ptr and the original unique_ptr no longer owns it. 
* std::shared_ptr: The shared_ptr uses reference counting to manage resources. A resource can be owned by more than one shared_ptr object. A shared_ptr stops owning a resource when it's reassigned or reset. When the last shared_ptr object that owns a particular resource is destroyed, the resource is freed. 
* std::weak_ptr: The weak_ptr is a way to solve the dangling pointer problem. By just using raw pointers it is impossible to know if the referenced data has been deallocated or not. Instead, by letting a shared_ptr manage the data, and supplying weak_ptr to users of the data, the users can check validity.
* std::auto_ptr: deprecated.
```
#include <memory>
#include <iostream>
using namespace std;

void uniquePtr() {
    auto p = make_unique<int>(3);
    auto p2 = move(p);
    cout << *p2 << endl;
}

void sharedPtr() {
    auto p = make_shared<int>(4);
    auto p2 = p;
    cout << *p << ", " << *p2 << endl;
}

void weakPtr() {
    weak_ptr<int> wp;
    {
        auto p = make_shared<int>(6);
        wp = p;
        if (auto sp = wp.lock()) {
            cout <<"Weak pointer is valid." <<endl;        
        }
    }
    if (auto sp = wp.lock() == NULL) {
        cout <<"Weak pointer is not valid." << endl;        
    }
}

int main()
{
    uniquePtr();
    sharedPtr();
    weakPtr();
    return 0;
}
/*
3
4, 4
Weak pointer is valid.
Weak pointer is not valid.
*/
```
* If you have a resource that’s really meant to be owned exclusively, using a shared_ptr instead of a unique_ptr makes the code susceptible to unwanted resource leaks and bugs. By default, you should use a unique_ptr. If a requirement comes up later to share the resource ownership, you can always change it to a shared_ptr.
* It’s a common mistake to assume that wrapping an object up in a shared_ptr makes it inherently thread safe. It’s still your responsibility to put synchronization primitives around the shared resource managed by a shared_ptr. If you do not plan on sharing the resource between multiple threads, use a unique_ptr.
* The auto_ptr feature was outright dangerous and has now been deprecated. unique_ptr does what auto_ptr was intended to do. You should do a search and find on your codebase and replace all auto_ptr with unique_ptr.