1. Unique pointers

std::unique_ptr is a scoped pointer which frees the heap memory once it goes out scope. Therefore it can not be copied since this could lead to situations in which the memory is freed multiple times. To prevent this, the copy constructor is deleted in the implementation. Hence call by value is not possible either.

Correct instantiation

std::unique_ptr<Cat> ptr1(new Cat(5));
std::unique_ptr<Cat> ptr2 = std::make_unique<Cat>(10); // preferred due to exception safety

// wrong
std::unique_ptr<Cat> ptr1 = new Cat(5);
// constructor is explicit

2. Shared pointers

Shared pointers can be copied and work via a reference count. Object dies only if all references are gone.

//good, more efficient memory allocation
std::shared_ptr<Cat> sharedCat = std::make_shared<Cat>(5);
// worse
std::shared_ptr<Cat> sharedCat2(new Cat(5));

3. Weak pointers

Weak pointer is like a helper for a shared pointer, but does not increase the ref coint of the underlying shared pointer and thus doesn’t increase it’s lifetime. Useful if you want to check and don’t take ownership of an object.

std::weak_ptr<Cat> weak;
        std::shared_ptr<Cat> sharedCat = std::make_shared<Cat>(5);
        weak = sharedCat;
        std::cout << "Weak pointer valid: " <<  weak.expired() << std::endl;
    std::cout << "Weak pointer valid: " <<  weak.expired() << std::endl;
Weak pointer valid: 0
Weak pointer valid: 1

Bjanre Stroustrup on the use of new