A smart pointer is a C++ class that encapsulates or wraps a standard C++ pointer. With raw pointers, the programmer has to explicitly destroy the object when it is no longer needed; smart pointers ensure the correct destruction of dynamically allocated data memory. 

C++11 introduced three types of smart pointers, all of them defined in the <memory> header found in the Standard Library:

unique_ptr

The unique_ptr<> is a scoped pointer that is automatically deleted when the object is destroyed, or as soon as its value is changed, either by using the assignment operation or by an explicit call to unique_ptr::reset.  A unique pointer cannot be copied.

The following code section generates 3 unique smart pointers and initialises them. When the function goes out of scope the memory allocated to the pointers is freed.

#include <iostream>
#include <string.h>
#include <memory>
using namespace std;
void smartptr()
{
//smart pointer to int
std::shared_ptr <int> intPtr(new int );  
//smart pointer to int array
std::shared_ptr <int> intarrayPtr(new int[100], std::default_delete<int[]>() );
// smart pointer to char array
std::shared_ptr <char> chararrayPtr(new char[100], std::default_delete<char[]>());
*intPtr=100;//set int value
intarrayPtr.get()[5]=5;//set int array value
strcpy(chararrayPtr.get(),"smart array");//set int char value
cout << "intPtr value: " << *intPtr<< endl;//out int value
cout << "intarrayPtr value: " << *(intarrayPtr.get()+5)<< endl;//out int array value
cout << "chararrayPtr value: " << (chararrayPtr.get())<< endl;//output int char value
}
int main()
{
smartptr();
//any attmempt to access the smart pointer values out of scope will fail
return 0;
}

shared_ptr

The shared_pointer is a smart pointer that can store and pass a reference beyond the scope of a function. shared_ptr instances share the ownership of the data which is only destroyed when all instances of the shared_ptr are removed. Reference Counting is a technique for storing the number of references to a particular resource.

#include <memory>
#include <iostream>
std::shared_ptr<int> func()
{
 std::shared_ptr<int> valuePtr(new int(15));
 return valuePtr; // no memory leak when smart pointer goes out of scope
}
 int main()
{
 std::shared_ptr <int> valuePtr1=func();
 std::cout << *valuePtr1;
}

weak_ptr

A weak_ptr is created as a copy of shared_ptr. It provides access to an object but does not participate in reference counting and does not affect the shared_ptr or its other copies. Users can check the validity of the data by calling expired() or lock() functions.

#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sPtr(new int(15));//create and initiate shared smart pointer
std::cout << "shared pointer value is " << *sPtr << "\n";
std::weak_ptr <int> wPtr = sPtr;//set weak pointer to shared pointer
*sPtr = 10;//change value of shared pointer
std::cout << "weak pointer value is " << *wPtr.lock()<< "\n";//weak pointer does not change
sPtr.reset();//delete shared pointer
if (wPtr.expired())//check if weak pointer exists
{
std::cout << "weak pointer value has been deleted";
}
}


In addition to the above, the C++ library includes the smaerstd::auto_ptr. This is now deprecated