C++ Program for User Defined Implementation of Shared Pointer

CPP
#include <iostream>
using namespace std;

// Class representing a reference counter class
class Counter 
{
public:
    // Constructor
    Counter() : m_counter(0){};

    Counter(const Counter&) = delete;
    Counter& operator=(const Counter&) = delete;

    // Destructor
    ~Counter() {}

    // count reset
    void reset()
    { 
      m_counter = 0;
    }

// getter
    unsigned int get() 
    { 
      return m_counter; 
    }

    // Overload post/pre increment
    void operator++() 
    { 
      m_counter++; 
    }

    void operator++(int) 
    { 
      m_counter++; 
    }

    // Overload post/pre decrement
    void operator--() 
    { 
      m_counter--; 
    }
    void operator--(int) 
    { 
      m_counter--; 
    }

    // Overloading << operator
    friend ostream& operator<<(ostream& os,
                               const Counter& counter)
    {
        os << "Counter Value : " << counter.m_counter
           << endl;
        return os;
    }

private:
    unsigned int m_counter{};
};


// Class template representing a shared pointer
template <typename T>
class Shared_ptr 
{
public:
    // Constructor
    Shared_ptr(T* ptr = nullptr)
    {
        m_ptr = ptr;
        m_counter = new Counter();
        (*m_counter)++;
    }

    // Copy constructor
    Shared_ptr(Shared_ptr<T>& sp)
    {
        // initializing shared pointer from other Shared_ptr object
        m_ptr = sp.m_ptr;
        
        // initializing reference counter from other shared pointer
        m_counter = sp.m_counter;
        (*m_counter)++;
    }

    // reference count getter
    unsigned int use_count() 
    { 
      return m_counter->get(); 
    }

    // shared pointer getter
    T* get() 
    { 
      return m_ptr;
    }

    // Overload * operator
    T& operator*() 
    { 
      return *m_ptr; 
    }

    // Overload -> operator
    T* operator->() 
    { 
      return m_ptr;
    }
    
    // overloading the = operator
    void operator= (Shared_ptr sp) {
        // if assigned pointer points to the some other location
        if (m_ptr != sp.m_ptr) {
            // if shared pointer already points to some location
            if(m_ptr && m_counter) {
                // decrease the reference counter for the previously pointed location
                (*m_counter)--;
                // if reference count reaches 0, deallocate memory
                if((m_counter->get()) == 0) {
                    delete m_counter;
                    delete m_ptr;
                }
            }
            // reference new memory location
            m_ptr = sp.m_ptr;
            // increase new memory location reference counter.
            if(m_ptr) {
                m_counter = sp.m_counter;
                (*m_counter)++;
            }
        }
    }
    
  
    // Destructor
    ~Shared_ptr()
    {
        (*m_counter)--;
        if (m_counter->get() == 0) 
        {
            delete m_counter;
            delete m_ptr;
        }
    }

    friend ostream& operator<<(ostream& os,
                               Shared_ptr<T>& sp)
    {
        os << "Address pointed : " << sp.get() << endl;
        os << *(sp.m_counter) << endl;
        return os;
    }

private:
    // Reference counter
    Counter* m_counter;

    // Shared pointer
    T* m_ptr;
};

int main()
{
    // ptr1 pointing to an integer.
    Shared_ptr<int> ptr1(new int(151));
    cout << "--- Shared pointers ptr1 ---\n";
    *ptr1 = 100;
    cout << " ptr1's value now: " << *ptr1 << endl;
    cout << ptr1;

    {
        // ptr2 pointing to same integer
        // which ptr1 is pointing to
        // Shared pointer reference counter
        // should have increased now to 2.
        Shared_ptr<int> ptr2 = ptr1;
        cout << "--- Shared pointers ptr1, ptr2 ---\n";
        cout << ptr1;
        cout << ptr2;

        {
            // ptr3 pointing to same integer
            // which ptr1 and ptr2 are pointing to.
            // Shared pointer reference counter
            // should have increased now to 3.
            Shared_ptr<int> ptr3(ptr2);
            cout << "--- Shared pointers ptr1, ptr2, ptr3 "
                    "---\n";
            cout << ptr1;
            cout << ptr2;
            cout << ptr3;
        }
        
        Shared_ptr<int> temp(new int(11));
        ptr2 = temp;

        // ptr3 is out of scope.
        // It would have been destructed.
        // So shared pointer reference counter
        // should have decreased now to 2.
        cout << "--- Shared pointers ptr1, ptr2 ---\n";
        cout << ptr1;
        cout << ptr2;
    }

    // ptr2 is out of scope.
    // It would have been destructed.
    // So shared pointer reference counter
    // should have decreased now to 1.
    cout << "--- Shared pointers ptr1 ---\n";
    cout << ptr1;

    return 0;
}

Output: 
--- Shared pointers ptr1 ---
Address pointed : 0x1cbde70
Counter Value : 1

--- Shared pointers ptr1, ptr2 ---
Address pointed : 0x1cbde70
Counter Value : 2

Address pointed : 0x1cbde70
Counter Value : 2

--- Shared pointers ptr1, ptr2, ptr3 ---
Address pointed : 0x1cbde70
Counter Value : 3

Address pointed : 0x1cbde70
Counter Value : 3

Address pointed : 0x1cbde70
Counter Value : 3

--- Shared pointers ptr1, ptr2 ---
Address pointed : 0x1cbde70
Counter Value : 2

Address pointed : 0x1cbde70
Counter Value : 2

--- Shared pointers ptr1 ---
Address pointed : 0x1cbde70
Counter Value : 1

 


How to Implement User Defined Shared Pointers in C++?

shared_ptr is one of the smart pointer introduced as a wrapper to the old raw pointers in C++ to help in avoiding the risks and errors of raw pointers. In this article, we will learn how to implement our own user defined shared pointer in C++.

Similar Reads

What is shared_ptr in C++?

A std::shared_ptr is a container for raw pointers. It is a reference counting ownership model i.e. it maintains the reference count of its contained pointer in cooperation with all copies of the std::shared_ptr. So, the counter is incremented each time a new pointer points to the resource and decremented when destructor of the object is called....

C++ Program for User Defined Implementation of Shared Pointer

CPP #include using namespace std; // Class representing a reference counter class class Counter { public: // Constructor Counter() : m_counter(0){}; Counter(const Counter&) = delete; Counter& operator=(const Counter&) = delete; // Destructor ~Counter() {} // count reset void reset() { m_counter = 0; } // getter unsigned int get() { return m_counter; } // Overload post/pre increment void operator++() { m_counter++; } void operator++(int) { m_counter++; } // Overload post/pre decrement void operator--() { m_counter--; } void operator--(int) { m_counter--; } // Overloading << operator friend ostream& operator<<(ostream& os, const Counter& counter) { os << "Counter Value : " << counter.m_counter << endl; return os; } private: unsigned int m_counter{}; }; // Class template representing a shared pointer template class Shared_ptr { public: // Constructor Shared_ptr(T* ptr = nullptr) { m_ptr = ptr; m_counter = new Counter(); (*m_counter)++; } // Copy constructor Shared_ptr(Shared_ptr& sp) { // initializing shared pointer from other Shared_ptr object m_ptr = sp.m_ptr; // initializing reference counter from other shared pointer m_counter = sp.m_counter; (*m_counter)++; } // reference count getter unsigned int use_count() { return m_counter->get(); } // shared pointer getter T* get() { return m_ptr; } // Overload * operator T& operator*() { return *m_ptr; } // Overload -> operator T* operator->() { return m_ptr; } // overloading the = operator void operator= (Shared_ptr sp) { // if assigned pointer points to the some other location if (m_ptr != sp.m_ptr) { // if shared pointer already points to some location if(m_ptr && m_counter) { // decrease the reference counter for the previously pointed location (*m_counter)--; // if reference count reaches 0, deallocate memory if((m_counter->get()) == 0) { delete m_counter; delete m_ptr; } } // reference new memory location m_ptr = sp.m_ptr; // increase new memory location reference counter. if(m_ptr) { m_counter = sp.m_counter; (*m_counter)++; } } } // Destructor ~Shared_ptr() { (*m_counter)--; if (m_counter->get() == 0) { delete m_counter; delete m_ptr; } } friend ostream& operator<<(ostream& os, Shared_ptr& sp) { os << "Address pointed : " << sp.get() << endl; os << *(sp.m_counter) << endl; return os; } private: // Reference counter Counter* m_counter; // Shared pointer T* m_ptr; }; int main() { // ptr1 pointing to an integer. Shared_ptr ptr1(new int(151)); cout << "--- Shared pointers ptr1 ---\n"; *ptr1 = 100; cout << " ptr1's value now: " << *ptr1 << endl; cout << ptr1; { // ptr2 pointing to same integer // which ptr1 is pointing to // Shared pointer reference counter // should have increased now to 2. Shared_ptr ptr2 = ptr1; cout << "--- Shared pointers ptr1, ptr2 ---\n"; cout << ptr1; cout << ptr2; { // ptr3 pointing to same integer // which ptr1 and ptr2 are pointing to. // Shared pointer reference counter // should have increased now to 3. Shared_ptr ptr3(ptr2); cout << "--- Shared pointers ptr1, ptr2, ptr3 " "---\n"; cout << ptr1; cout << ptr2; cout << ptr3; } Shared_ptr temp(new int(11)); ptr2 = temp; // ptr3 is out of scope. // It would have been destructed. // So shared pointer reference counter // should have decreased now to 2. cout << "--- Shared pointers ptr1, ptr2 ---\n"; cout << ptr1; cout << ptr2; } // ptr2 is out of scope. // It would have been destructed. // So shared pointer reference counter // should have decreased now to 1. cout << "--- Shared pointers ptr1 ---\n"; cout << ptr1; return 0; }...