Click here to Skip to main content
Click here to Skip to main content

Understanding & Implementing Smart Pointer in C++

By , 9 Feb 2012
Rate this:
Please Sign up or sign in to vote.

Introduction

Now we have new C++ standards with us. The new standards have taken into account some of the real good features which were missing in C++. But this article has nothing to do with C++11. perhaps my future articles will talk about them, but this article talks about the smart pointers and contains a rudimentary implementation of "auto_ptr".

Background

One of the major benefits of using C++ is its deterministic nature. Using C++, we can deterministically control our memory allocation and deallocation (new and delete). But sometimes this becomes a problem. If a novice programmer forgets to delete any object created by new, then we have a memory leak. In case of long running systems, even small memory leaks will create bigger problems. So how can we ensure that for every new, there is a corresponding delete.

One way to do so is to use auto_ptr available in C++. auto_ptr transfers the ownership on copy operations, but if we need shared ownership then perhaps we can use boost libraries' smart pointers. But to really understand how these things must be working internally, we need to first implement them. Implementing smart pointers gives us the full understanding of why we need smart pointers, how they are working underneath and where to look for if we have some bug. This exercise here is an implementation of auto_ptr. The main idea is to understand how auto_ptr takes care of transfer of ownership and using various other operations.

Using the Code

The project contains two main classes. Our implementation of smart pointer is in MyAuto_Ptr and other class to test this smart pointer MyTestObject. The test suite is written in the main class.

I have put in comments in all the places where we need to know what that code is doing so without talking any more, I give you the code.

The Test Class

class MyTestObject
{
    string name;
    int age;

public:
    MyTestObject(string s, int a)
    {
        name = s;
        age = a;
        cout << "Object created\n";
    }

    ~MyTestObject(void)
    {
        cout << "Object destroyed\n";
    }

    string GetName()
    {
        return name;
    }

    int GetAge()
    {
        return age;
    }
};

Our Smart Pointer

template <class T>
class MyAuto_Ptr
{
private:
    T *ptr;

public:

    //Constructor
    explicit MyAuto_Ptr(T *p = 0)
        :ptr(p)
    {

    }

    //Destructor
    ~MyAuto_Ptr(void)
    {
         delete ptr;
    }

    //Copy constructor
    MyAuto_Ptr(MyAuto_Ptr<T> &source)
    {
        ptr = source.ptr;

        //Since the ownership gets transferred lets point the source to 0
        source.ptr = 0;
    }

    MyAuto_Ptr& operator=(MyAuto_Ptr<T> &source)
    {
        //check for self reference
        if(ptr != source.ptr)
        {
            //flush the existing memory
            delete ptr;
            ptr = 0;

            // use the new pointer
            ptr = source.ptr;

            //Since the ownership gets transferred lets point the source to 0
            source.ptr = 0;

            return *this;
        }
    }

    //Access the value of pointer
    T& operator *()
    {
        return *ptr;
    }

    //Access the pointer
    T* operator ->()
    {
        return ptr;
    }

    //Get the value of pointer
    T* get()
    {
        return ptr;
    }

    //reset the value of pointer
    void reset(T *newVal)
    {
        delete ptr;
        ptr = newVal;
    }

    //release the pointer and returns the ownership
    T* release()
    {
        T *t = ptr;
        ptr = 0;
        return t;
    }
};

Testing the Class (Main)

int main(int argc, char* argv[])
{
    {//dummy brace to test the destruction
        MyAuto_Ptr<MyTestObject> p(new MyTestObject("Rahul Singh", 29));

        //test the -> operator
        cout << "Name: " << p->GetName() << ", Age: " << p->GetAge() << "\n";

        //test the transfer of ownership in copy constructor
        MyAuto_Ptr<MyTestObject> p2(p);

        //test the * operator
        cout << "Name: " << (*p2).GetName() << ", Age: " << (*p2).GetAge() << "\n";

        //test the transfer of ownership in assignment operator
        MyAuto_Ptr<MyTestObject> p3;
        p3 = p2;

        //test the get function
        cout << "Name: " << p3.get()->GetName() << ",
            Age: " << p3.get()->GetAge() << "\n";

        //lets test the reset function
        p3.reset(new MyTestObject("Megha Singh", 28));

        //test the get function
        cout << "Name: " << p3.get()->GetName() << ",
            Age: " << p3.get()->GetAge() << "\n";

        //finally lets test the release function
        MyAuto_Ptr<MyTestObject> p4(p3.release());

        cout << "Name: " << p4.get()->GetName() << ",
            Age: " << p4.get()->GetAge() << "\n";
    }
    getchar();
    return 0;
}

NOTE: Please refer to the source code for implementation details.

Points of Interest

This exercise is something I did long ago when one of my mentors (also best of all) told me that the best way to learn something is to get your hands dirty and just do it. Since I wrote this in the very beginning of my career (almost 6 years ago), it was very helpful in understanding the basics. I suggest that all new C++ programmers should do the same exercise and it will make them understand things better.

History

  • MyAuto_Ptr: Implementation of auto_ptr
  • Changed the Implementation as suggested in the comments (Thanks for the valuable inputs)
  • ToDo: MySharedAuto_Ptr: Implementation of shared_ptr (I will post that soon)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Rahul Rajat Singh
Software Developer (Senior)
India India
I Started my Programming career with C++. Later got a chance to develop Windows Form applications using C#. Currently using C#, ASP.NET & ASP.NET MVC to create Information Systems, e-commerce/e-governance Portals and Data driven websites.

My interests involves Programming, Website development and Learning/Teaching subjects related to Computer Science/Information Systems. IMO, C# is the best programming language and I love working with C# and other Microsoft Technologies.
Follow on   Twitter   Google+   LinkedIn

Comments and Discussions

 
QuestionTransfer of ownership was exact downfall of auto_ptr Pinmembersteveb9-Feb-12 7:26 
QuestionDitto for release Pinmemberunitrunker8-Feb-12 11:37 
QuestionTrivial bug in reset Pinmemberunitrunker8-Feb-12 11:34 
Questiondelete ptr PinmemberGiacomo Pozzoni8-Feb-12 11:15 
Questionshared_ptr and unique_ptr already in C++ PinmemberGurliGebis8-Feb-12 9:35 
AnswerRe: shared_ptr and unique_ptr already in C++ PinmemberJackDingler8-Feb-12 10:06 
AnswerRe: shared_ptr and unique_ptr already in C++ PinmemberJackDingler9-Feb-12 5:05 
GeneralRe: shared_ptr and unique_ptr already in C++ PinmemberAescleal16-Apr-12 0:29 
GeneralRe: shared_ptr and unique_ptr already in C++ PinmemberJackDingler16-Apr-12 12:00 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140415.2 | Last Updated 9 Feb 2012
Article Copyright 2012 by Rahul Rajat Singh
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid