SMART POINTERS IN C++

 Smart Pointers:
a) A smart pointer is a wrapper over a raw pointer that automatically manages memory, ensuring proper deallocation and preventing memory leaks.  
b) Smart pointers are template-based, allowing use with any data type.
c) They all are declared in <memory> header file.

1) auto_ptr

2) unique_ptr
3) shared_ptr
4) weak_ptr

1) auto_ptr:

a) An object when described using the auto_ptr class, stores a pointer to a single allocated object which ensures that when it goes out of scope, the object it points to must get automatically destroyed. 
b) It is based on an exclusive ownership model i.e. two pointers of the same type can’t point to the same resource at the same time. 

Example:

#include<iostream>
using namespace std;

class Class_S

{
public:
  void Show()
{
cout << "Class_S :: Show" << endl;
}
};

int main()

{
            //raw pointer
            cout << "raw pointer" << endl;
 Class_S* s = new Class_S();
    s->Show();
            cout << "raw pointer s address:  " << s << endl;
            cout << endl;
    
            cout << "auto pointer - p1" << endl;
            // p1 is an auto_ptr 
            auto_ptr<Class_S> p1(new Class_S);
            p1->Show();
            // returns the memory address of p1
            cout << "auto pointer p1 address:  " << p1.get() << endl;
            cout << endl;

    
            cout << "auto pointer - p2" << endl;
            // copy constructor called, this makes p1 empty.
            auto_ptr<Class_S> p2(p1);
            p2->Show();

            // p1 gets copied in p2

            cout << "auto pointer p2 address:  " << p2.get() << endl;
            cout << endl;
            
            // p1 is empty now
            cout << "auto pointer p1 address:  " << p1.get() << endl;    
 return 0;
}


2) unique_ptr:
a) std::unique_ptr was developed in C++11 as a replacement for std::auto_ptr. 
b) It is a container for raw pointers. 
c) When using unique_ptr there can only be at most one unique_ptr at any one resource and when that unique_ptr is destroyed, the resource is automatically claimed.

Example:

#include<iostream>
using namespace std;

class Class_S

{
public:
  void Show()
{
cout << "Class_S :: Show" << endl;
}
};

int main()

{
  cout << "unique ptr - u1" << endl;
unique_ptr<Class_S> u1(new Class_S);
u1->Show();
cout << "address of u1: " << u1.get() << endl;
cout << endl;

cout << "unique ptr - u2" << endl;
unique_ptr<Class_S>u2 = move(u1);
u2->Show();
cout << "address of u2: " << u2.get() << endl;
cout << endl;

// u1 is empty now
cout << "u1 address:  " << u1.get() << endl;
return 0;
}

3)shared_ptr:

a) A shared_ptr is a container for raw pointers. 
b) It is a reference counting ownership model.
c) The counter is incremented each time a new pointer points to the resource and decremented when the destructor of the object is called. 
d) An object referenced by the contained raw pointer will not be destroyed until the reference count is greater than zero.
e) we should use shared_ptr when we want to assign one raw pointer to multiple owners. 

Example: 

#include<iostream>
using namespace std;

class Class_S

{
public:
    void Show()
    {
        cout << "Class_S :: Show" << endl;
    }
};

int main()

{
        cout << "Shared ptr p1" << endl;
        shared_ptr<Class_S> p1(new Class_S);
        cout << "address of p1: " << p1.get() << endl;
        p1->Show();

        cout << "Shared ptr p2" << endl;

        shared_ptr<Class_S> p2(p1);
        p2->Show();

        cout << "address of p1: " << p1.get() << endl;

        cout << "address of p2: " << p2.get() << endl;

        // Returns the number of shared_ptr objects

        // referring to the same managed object.
        cout << "p1.use_count() = " << p1.use_count() << endl;
        cout << "p2.use_count() = " << p2.use_count() << endl;

        // Relinquishes ownership of p1 on the object

        // and pointer becomes NULL
        p1.reset();

        cout << "address of p1: " << p1.get() << endl;

        cout << "p2.use_count() = " << p2.use_count() << endl;
        cout << "address of p2: " << p2.get() << endl;

        return 0;

}

4) weak_ptr:

a) A weak_ptr is created as a copy of shared_ptr. 
b) It provides access to an object that is owned by one or more shared_ptr instances but does not participate in reference counting. 
c) The existence or destruction of weak_ptr has no effect on the shared_ptr or its other copies. 
d) It is required in some cases to break circular references between shared_ptr instances.
 
Example:
#include<iostream>
using namespace std;

class Class_S

{
public:
    void Show()
    {
        cout << "Class_S :: Show" << endl;
    }
};

int main()

{
        cout << "Shared ptr p1" << endl;
        shared_ptr<Class_S> p1(new Class_S);
        cout << "address of p1: " << p1.get() << endl;
        p1->Show();
    
        // creating weak pointer to the previously created
        // shared objects
        weak_ptr<Class_S> weakObjectA = p1;
    
        // Access objects using weak_ptr
        if (!weakObjectA.expired()) 
        {
            cout << "WeakObject: " << endl;
            (*weakObjectA.lock()).Show();
            cout << endl;
        }
 

        // deleting object
        p1.reset();
    
        return 0;
}

Popular posts from this blog

OBJECT ORIENTED ANALYSIS AND DESIGN (OOAD)

OBJECT ORIENTED PROGRAMMING

STARTING A BUSINESS