SmartPointers

Overview
Internally C/C+++ runtime does not have garbage collector support therefore  dangling pointers, leaked resources causes instability in applications. Smartpointers are  used to get around this issue. 

Details
In C++ 11, new smartpointers were introduced as discussed below.

nullptr_t
NULL is defined as macro, represented as an integer of value 0. However it's misused to represent null pointers as shown below.
#define NULL 0
int *iptr = NULL;

nullptr_t data type is introduced specifically to prevent misuse of NULL in place of null pointers. nullptr is the only instance of this type.  It is a distinct type that is not itself a pointer type or a pointer to member type. Prvalues of this type are null pointer constants, and may be implicitly converted to any pointer and pointer to member type.
Syntax
using nullptr_t = decltype(nullptr);
Note that  sizeof(std::nullptr_t) is equal to sizeof(void *).

nullptr can be used in place of  NULL for pointers.
int *intptr = nullptr;
This example 19 and its console output.  demonstrates its usage in various scenarios.

Generic smartpointer
A Smartpointer is basically a RAII (Resource Acquisition Is Initialization) object that wraps a pointer to an object or an array. When the smartpointer object is destroyed, the underlying memory of the pointer is released. A smartpointer uses dereferencing operators such as [], * and -> to access the object or its members the pointer is inferring.
The example, depicts such an implementation.
template<typename T>
struct smartptr
{
    smartptr(T *ptr):m_ptr(ptr) {};
    ~smartptr() {delete m_ptr;}
    T& operator*() {return *m_ptr;}
    T* operator->() {return m_ptr;}

    T* m_ptr;
};

template<typename T>
struct smartptr<T[]>
{
    smartptr(T ptr[]):m_ptr(ptr) {};
    ~smartptr() {delete[] m_ptr;}
    T& operator[](size_t i) {return m_ptr[i];}

    T* m_ptr;
};

struct person
{
    ~person()
    {
        cout << "~person() called" << endl;
    }

    string name;
    int age;
};

{    
    /*prints
    smartptr<person> a(new person{"Khrisha",6})
    name = Khrisha
    age = 6
    ~person() called
    */
    cout << R"(smartptr<person> a(new person{"Khrisha",6}))" << endl;
    smartptr<person> x(new person{"Khrisha",6});
    cout << "name = " << (*x).name << endl;
    cout << "age = " << x->age << endl;
}
    cout << endl;


{    
    /*prints
   smartptr<person[]>  y(new person[]{{"Khrisha",6}}
    name = Khrisha
    age = 6
    ~person() called
    */

    cout << R"(smartptr<person[]>  y(new person[]{{"Khrisha",6}})" << endl;
    smartptr<person[]>  y(new person[]{{"Khrisha",6}});
    cout << "name = " << y[0].name << endl;
    cout << "age = " << y[0].age << endl;
}   

default_delete is a functor object. aka deleter  object used by smartpointers like unique_ptr to recycle the resources.

unique_ptr is similar to a smartpointer, owns the underlying resource such as memory or a file handle. It can have custom deleter object to release the resource.

Sometimes a resource needs to be shared across without duplication. An unique_ptr discussed above cannot be used in such cases. 
For example, a chat server needs to share a message its clients without duplication. 
shared_ptr addresses this issue. Unlike a unique_ptr, the underlying resource is collectively owned by a set of  shared_ptrs.  The underlying resource is released when the last instance of shared_ptr goes out of scope.

Sometimes it's undesirable to have a resource exist beyond its need.
For example, an airline ticketing application holds several time bound discounted ticket offers that expire after certain period.
A weak_ptr is a smart pointer that holds a non-owning ("weak") reference to an object that is managed by shared_ptr. It must be converted to shared_ptr in order to access the referenced object. A client holding a weak_ptr  basically checks if it's not expired(), later it's converted to a shared_ptr for accessing the resource.

Summary of Examples
NameDescriptiongithub$$wandbox
  Examplegeneric smartpointersource    output   source + output 
  Example 2unique_ptr - Constructorssource    output   source + output 
  Example 3unique_ptr - Methodssource    output   source + output 
  Example 4unique_ptr - Double LL Examplesource    output   source + output
  Example 5shared_ptr - Constructorssource    output   source + output
  Example 6shared_ptr - Methodssource    output   source + output
  Example 7shared_ptr - make_sharedsource    output   source + output
  Example 8shared_ptr - allocate_sharedsource    output   source + output
  Example 9shared_ptr - castsource    output   source + output
  Example 10shared_ptr - owner_lesssource    output   source + output  
  Example 11shared_ptr - enable_shared_from_this issuesource    output   source + output  
  Example 12shared_ptr - enable_shared_from_this solutionsource    output   source + output  
  Example 13shared_ptr - Double LL Examplesource    output   source + output  
  Example 14shared_ptr - chat server examplesource    output   source + output  
  Example 15weak_ptr - Constructorssource    output   source + output  
  Example 16weak_ptr - Methodssource    output   source + output  
  Example 17weak_ptr - Airline Ticket Offer Exampsource    output   source + output  
  Example 18weak_ptr - Double LL Examplesource    output   source + output  
  Example 19nullptr_t    source    output   source + output  

Included in Header file: <memory>

No comments:

Post a Comment