Smart Pointers – Part II

Illustrate the concept of Garbage Collection in C++ programming.
In this part we implement a Garbage Collection with C++.

Keywords:

-Lifetime:
The period during witch an object exist, is the “Lifetime” of this object.

-Access Path:
“Access Path” to an object is the path that can access to an object.

-Garbage:
If all Access Paths to a Data Object (DO) loses, this Data Object is like “Garbage” in the memory.

-Dangling Reference:
If “Lifetime” of each Data Object (DO) was finished, when there is at least one “Access Path” to it, all Access Paths are “Dangling Reference”.

Example of Garbage:

int *  pi1 =  new int; // first DO
int *  pi2 =  new int; // second DO
pi2 = pi1;  //  now pi1 and pi2 refer to first DO 
                //   and the all access path to the second DO loses;

Example of Dangling Reference:

int  * pi = new int; // first DO
delete pi;
...
//use the pi makes runtime error

Now we want to solve garbage problem, which named Garbage Collection.

One of the ways that solve this problem is:
1.Delete all data objects that create using new or malloc.
2.When delete a reference to a data object don’t forget assign NULL to the pointer.

But I write a class in C++ that if I and you forgot the two rules above.

In this Class I use below techniques and if you don’t know one of them I suggested that you learn these techniques before reading the code.
-Templates
-Smart Pointers
-Overloading operators
-And other object oriented techniques.

template<typename T>
class CDataPacket
{
private:
    int RefNum;
public:
    T* pData;
    CDataPacket();
    ~CDataPacket();
    void DecRef();
    void IncRef();
};

This class provides a data object that can be reference to a user data object, and count the references to it, and increment and decrement the reference counter.

In this object when the references counter equal to zero, user data object and this object deleted.

template<typename T>
class CPtr
{
private:
    CDataPacket<T> * Refs;
public:
    ~CPtr();
    CPtr();
    T* operator->();
    T & operator*();
    operator T*();
    CPtr<T>& operator = ( T* p);
    CPtr<T>& operator = ( CPtr<T>& p);
};

This class provide an interface for users that can work with this object like the pointers, also this class administrate the assignments, because in assignments references increment and decrement.

Below is the implementation of above classes.

template<typename T>
void CDataPacket<T>::DecRef()
{
    if (RefNum == 0) return;
 
    RefNum--;
    if (RefNum == 0)
        delete this;
}
 
template<typename T>
void CDataPacket<T>::IncRef()
{
    RefNum++;
}
 
template<typename T>
CDataPacket<T>::CDataPacket()
{
    pData = NULL;
    RefNum = 0;
}
 
template<typename T>
CDataPacket<T>::~CDataPacket()
{
    delete pData;
}
template<typename T>
CPtr<T>& CPtr<T>::operator= ( T* p)
{
    if ( Refs)
        Refs->DecRef();
    Refs = new CDataPacket<T>;
    Refs->pData = p;
    Refs->IncRef();
    return *this;
}
 
template<typename T>
CPtr<T>& CPtr<T>::operator= ( CPtr<T>& p)
{
    if ( Refs)
        Refs->DecRef();
    Refs = p.Refs;
    Refs->IncRef();
    return *this;
}
 
template<typename T>
CPtr<T>::~CPtr()
{
    Refs->DecRef();
}
 
template<typename T>
CPtr<T>::CPtr()
{
    Refs = NULL;
}
 
template<typename T>
T* CPtr<T>::operator ->()
{
    return Refs->pData;
}
 
template<typename T>
T& CPtr<T>::operator *()
{
    return *(Refs->pData);
}
 
template<typename T>

CPtr<T>::operator T*()

{

      return Refs->pData;

}

Example of using these classes:

Ex1:

void main()
{
      CPtr<int> pii;
      pii = new int[10];
      pii[0]=0;
      pii[2]=10;
      cout << pii[0] << endl;
      cout << pii[2] << endl;
}

Output:
0
10

Ex2:

class test
{
private:
      int data;

public:
      test(int i){ data = i;};
      ~test(){ cout << " class #"<<data<<" destroyed."<< endl; };
      void DoSomeThing(){ cout << " class #"<<data<<" doing something."<< endl; };
};
void main()
{
      CPtr<test> ts,ts1,ts2;

      ts = new test(0);
      ts1 = new test(1);
      ts2 = new test(2);      

      ts->DoSomeThing();      // output in line 1
      ts1->DoSomeThing();     // output in line 2
      ts2->DoSomeThing();     // output in line 3

      ts = ts1;               // output in line 4
      ts1 = ts2;              

      ts->DoSomeThing();      // output in line 5
      ts1->DoSomeThing();     // output in line 6
      ts2->DoSomeThing();     // output in line 7

      ts1 = ts;

      ts->DoSomeThing();      // output in line 8
      ts1->DoSomeThing();     // output in line 9
      ts2->DoSomeThing();     // output in line 10

      (*ts).DoSomeThing();    // output in line 11
}                             // output in line 12,13

Output:

1: class #0 doing something.
2: class #1 doing something.
3: class #2 doing something.
4: class #0 destroyed.
5: class #1 doing something.
6: class #2 doing something.
7: class #2 doing something.
8: class #1 doing something.
9: class #1 doing something.
10: class #2 doing something.
11: class #1 doing something.
12: class #2 destroyed.
13: class #1 destroyed.

Have a Goooood Day, with more errorless programming.

Nathan Pakovskie is an esteemed senior developer and educator in the tech community, best known for his contributions to Geekpedia.com. With a passion for coding and a knack for simplifying complex tech concepts, Nathan has authored several popular tutorials on C# programming, ranging from basic operations to advanced coding techniques. His articles, often characterized by clarity and precision, serve as invaluable resources for both novice and experienced programmers. Beyond his technical expertise, Nathan is an advocate for continuous learning and enjoys exploring emerging technologies in AI and software development. When he’s not coding or writing, Nathan engages in mentoring upcoming developers, emphasizing the importance of both technical skills and creative problem-solving in the ever-evolving world of technology. Specialties: C# Programming, Technical Writing, Software Development, AI Technologies, Educational Outreach

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top