Saturday, April 5, 2014

Smart pointer in C++

Problem

Write a smart pointer (smart_ptr) class.

Solution

As discussed here, smart pointers are C++ objects that simulate simple pointers by implementing operator-> and the unary operator*. In addition to sporting pointer syntax and semantics, smart pointers often perform useful tasks—such as memory management or locking—under the covers, thus freeing the application from carefully managing the lifetime of pointed-to objects. You can read more about it on the provided link. Also, if you want to go into the details - refer http://ootips.org/yonat/4dev/smart-pointers.html.

Lets answer the solution:

template <class T>
class smart_ptr {
    T * ptr;
    int count;
    public:
    smart_ptr() {
        ptr = new T;
        count = 1;
    }
     
    ~smart_ptr() {
        count = count - 1;
        if(count == 0)
            delete ptr;
    }
     
    smart_ptr(const smart_ptr & other) {
        ptr = other.ptr;
        count++;
    }
     
    smart_ptr operator=(const smart_ptr & other) {
        smart_ptr result = new smart_ptr(other);
        return result;
    }
};

Smart_ptr is the same as a normal pointer, but it provides safety via automatic memory. It avoids dangling pointers, memory leaks, allocation failures etc. The smart pointer must maintain a single reference count for all instances.
template <class T> class SmartPointer {
public:
    SmartPointer(T * ptr) {
        ref = ptr;
        ref_count = (unsigned*)malloc(sizeof(unsigned));
        *ref_count = 1;
    }
     
    SmartPointer(SmartPointer<T> & sptr) {
        ref = sptr.ref;
        ref_count = sptr.ref_count;
        ++*ref_count;
    }
     
    SmartPointer<T> & operator=(SmartPointer<T> & sptr) {
        if (this != &sptr) {
            ref = sptr.ref;
            ref_count = sptr.ref_count;
            ++*ref_count;
        }
        return *this;
    }   
     
    ~SmartPointer() {
        --*ref_count;
        if (*ref_count == 0) {
            delete ref;
            free(ref_count);
            ref = NULL;
            ref_count = NULL;
        }
    }
     
    T & operator*() {return *ptr;}
    T * operator->() {return ptr;}
protected:  
    T * ref;
    unsigned * ref_count;
};

The way that we are using a unsigned pointer to the reference counting is similar as declare it to be static in Java, i.e., all the instances of smart_ptr will share one single copy of the reference counting.

References 

0 comments:

Post a Comment