C++ Program for User Defined Implementation of Shared Pointer
#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++.