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

Shared_Pointer

, 19 May 2008
Rate this:
Please Sign up or sign in to vote.
Implementation of Shared Pointer

introduction

smart pointers are classes that store pointers to dynamically allocated (heap) objects. they behave much like built-in c++ pointers except that they automatically delete the object pointed to at the appropriate time. smart pointers are particularly useful in the face of exceptions as they ensure proper destruction of dynamically allocated objects. they can also be used to keep track of dynamically allocated objects shared by multiple owners.

one of the most important techniques of implementing smart pointers is using reference count method.most of you have rolled your own smart pointers, and there is plenty of literature regarding the issues involved in reference counting. one of the most important details is how the reference count is implemented — intrusive, which means that you add support to the classes being reference counted, or non-intrusive, which means you don’t. my implementation is non-intrusive, and the implementation uses a simple integer reference counter.

background

you must know the basic concepts of parameter passing of c++ to understand the reference counting mechanism. in c++,we have two types of parameter passing:

1)pass by value.
2)pass by reference.
in pass by value,a temporary copy of the data type being passed is created.in pass be reference, the address of the parameter being passed is sent so that any changes to the passed parameter is directly reflected to the state of the passed parameter.

now,if we pass and user-defined object as a parameter to a function,the copy-constructor of the function is called to create a temporary object,which is destroyed as soon as the function returns. i have used this concept to create the shared pointer implementation for automatic garbage collection.

using the code

this is a very simple implementation of the shared pointer concept. i have used a templated class which wraps a pointer to a reference counting object. this object wraps the pointer to the class passed as the template argument.

the implementation is very simple. it has a de-referencing operator which returns the wrapped pointer object when used. whenver, the shared pointer is passed as a argument to function or any situation in which a copy constructor is involved,its reference count is incremented. this reference count is decremented in the destructor which when it reaches 0,the wrapped pointer is freed.
:

///////////////////////////////////////////////////////////////////
///this class implements the reference counting mechanism for the
////////////////////////////class.////////////////////////////////
//////////////////////////////////////////////////////////////////
template <class t> class refcounter_impl {
    private:
    int m_counter;
    t* m_obj;
    public:
    void inc_ref_count() 
    {
        ++m_counter; 
    }
    void dec_ref_count()
    {
        --m_counter;
        if(m_counter<=0)
        {
           destroy_ref();
        }
    }
    t * get_ptr() const
    {
        return ((t *)this);
    }
    void destroy_ref() 
    { 
        if(get_ptr()!=null)
            delete get_ptr();
    }    
    const t& operator=(const refcounter_impl<t>& ref)
    {
        this->m_obj = ref.m_obj;
        m_counter = ref.m_counter;
        inc_ref_count();
    }
    refcounter_impl(t* obj):m_counter(0),m_obj(obj){}
    refcounter_impl(const refcounter_impl<t>& ref)
    {
        this->m_obj = ref.m_obj;
        m_counter = ref.m_counter;
        inc_ref_count();
    }
    
}; 
 
//this is the shared_ptr implementation of the class template 
<class t>
class shared_ptr
{
private:
    refcounter_impl<t>* m_refcounted_obj;    
    void assign(void *ptr)
    {
        if(ptr==null)
            assign((refcounter_impl<t> *)null);
        else
        {
            assign(new refcounter_impl<t>(static_cast<t *>(ptr)));
        }
    }
    void assign(refcounter_impl<t> *refcount)
    {                
        if(refcount!=null)
            refcount->inc_ref_count();
        m_refcounted_obj = refcount;        
    }
public:        
    shared_ptr() :m_refcounted_obj(null){}
    shared_ptr(t* obj) :m_refcounted_obj(null)
    {
        assign(obj);
    }
    shared_ptr(const shared_ptr& ref)
    {        
        assign(ref.m_refcounted_obj);
    }
    shared_ptr& operator=(const shared_ptr& ref)
    {
        assign(ref.m_refcounted_obj);
        return *this;
    }
    t* operator->()
    {
        if(m_refcounted_obj)
            return m_refcounted_obj->get_ptr();
        else
            return null;
    }
    ~shared_ptr()
    {
        m_refcounted_obj->dec_ref_count();
    }

}; 

conclusion

  • this is a very simple implementation of the shared pointer technique,and i have kept this deliberately for intermediate users. advanced users might not refer this article but this would extremely useful for people with 2-3 years of development experience moving on to implementing bigger things.

points of interest

  • i particularly enjoyed to explore the c++ argument passing mechanism while writing this article.
  • you can download the concepts.zip folder to see the complete c++ code with an example of my implementation.

License

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

About the Author

Abhi_Coder
Software Developer (Senior) Globallogic
India India
No Biography provided

Comments and Discussions

 
QuestionMaybe has memory leak? PinmemberMember 3145669-May-12 22:08 
GeneralThanks! Pinmemberferahl15-Jul-09 13:54 
Generalas of July 2, 2008, this is still broken PinmemberKevinSeghetti2-Jul-08 12:57 
Generaloh! Pinmemberecyrbe19-May-08 9:25 
GeneralRe: oh! PinmemberAbhi_Coder20-May-08 2:34 
GeneralI'm sorry, this is simply not going to work PinmemberIvo Beltchev19-May-08 7:40 
GeneralRe: I'm sorry, this is simply not going to work PinmemberAbhi_Coder20-May-08 2:32 

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.140718.1 | Last Updated 19 May 2008
Article Copyright 2008 by Abhi_Coder
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid