smart_pointer is a blessing for a carefree programmer who wants to allocate memory in heap and forget about deleting it. Sounds great. Its really tough to track a pointer and carefully release the heap memory captured.
Also it relies on the fact that its easy to clear stack than heap. So, lets see how it works.
First lets see, how can we use a smart pointer class in our program and then we will go ahead to implement it. Please follow the comments for understanding.
We take an example class
class A
{
public:
//This variable is meant to track the
// number of instances of the class that are existing.
static int count;
//Constructor
A()
{
//New instance is created so increment.
count++;
}
//Copy contstructor
A(A& obj)
{
//New instance is created so increment
count ++;
}
//Assignment operator
A& operator =(A& obj)
{
//New instance is created so increment
count ++;
}
~A()
{
//Instance removed, so decrement the value.
count --;
}
void display()
{
cout << "Its me \n";
}
};
Now we look at the main function where we will be using the smart_ptr class.
int main()
{
//This is how we create a smart_ptr object
// see the pointer of type A is stored inside the
// smart_ptr object
smart_ptr<A> ptr(new A());
smart_ptr<A> ptr1;
//Testing assignment operator
ptr1 = ptr;
//Testing self assignment
ptr = ptr;
// Verifying how many instances of A are there.
cout << "A::count = " << A::count << endl;
//Using overloaded -> operator to call
// member functions of class A
ptr->display();
}
Now we implement the smart_ptr class, as per the usage. So, here it is.
template <class T>
class smart_ptr
{
private:
// The pointer which is managed
// by the smart_ptr class
T* m_ptr;
//Keeps track of the number of references
//the allocated memmory.
int ref_count;
public:
smart_ptr()
{
m_ptr = 0;
ref_count = 0;
}
smart_ptr(T* ptr)
{
m_ptr = ptr;
//increment the ref count
//as this is the first reference
ref_count = 1;
}
smart_ptr(smart_ptr& obj)
{
cout << "Copy Contstructor\n";
ref_count++;
}
//Assignment operator overload
smart_ptr* operator =(smart_ptr& obj)
{
if(&obj != this)
{
ref_count++;
}
else
{
cout << "Self assignment\n";
}
}
// Destructor
~smart_ptr()
{
cout << "Deleteing the smart_ptr instance\n";
// Decrement the reference count as
// the instance is released
ref_count --;
if(ref_count == 0)
{
// Delete the pointer
// as there are no references to it.
delete m_ptr;
}
}
T* operator ->()
{
return m_ptr;
}
};