Efficient smart pointer implementation in C++ The idea behind this is mainly educational but I might even consider using it in reality if turns out to be good. Here's my first try at implementing smart pointers:

template&lt;typename T&gt;
class smart_pointer{
    T* pointer;
    std::size_t *refs;

    void clear(){
        if (!--*refs){
            delete pointer;
            delete refs;
        }
    }

public:
    smart_pointer(T* p = NULL)
        : pointer(p), refs(new std::size_t(1))
    {}
    smart_pointer(const smart_pointer&lt;T&gt;&amp; other)
        : pointer(other.pointer), refs(other.refs)
    {
        ++*refs;
    }
    ~smart_pointer(){
        clear();
    }

    smart_pointer&lt;T&gt;&amp; operator=(const smart_pointer&lt;T&gt;&amp; other){
        if (this != &amp;other){
            clear();

            pointer = other.pointer;
            refs    = other.refs;
            ++*refs;
        }
        return *this;
    }

    smart_pointer&lt;T&gt;&amp; operator=(T* p){
        if (pointer != p){
            pointer = p;
            *refs = 1;
        }
        return *this;
    }

    T&amp; operator*(){
        return *pointer;
    }

    const T&amp; operator*() const{
        return *pointer;
    }

    T* operator-&gt;(){
        return pointer;
    }

    const T* operator-&gt;() const{
        return pointer;
    }

    std::size_t getCounts(){
        return *refs;
    }
};


I have tested this under valrind and its clean. Also, to see how much the "smartness" makes things slower, I did the following test:

struct foo{
    int a;
};

template&lt;typename pointer_t&gt;
class bar{
    pointer_t f_;

public:
    bar(foo *f)
        :f_(f)
    {}

    void set(int a){
        f_-&gt;a = a;
    }
};

int main()
{
    foo *f = new foo;

    typedef smart_pointer&lt;foo&gt; ptr_t;
//    typedef boost::shared_ptr&lt;foo&gt; ptr_t;
//    typedef foo* ptr_t;

    bar&lt;ptr_t&gt; b(f);
    for (unsigned int i = 0; i&lt;300000000; ++i)
        b.set(i);

//    delete f;
    return 0;
}


Here is some timing between my implementation, boost, and raw pointers: (code compiled with clang++ -O3)

typedef smart_pointer&lt;foo&gt; ptr_t;

real   0m0.006s
user   0m0.001s
sys    0m0.002s

typedef boost::shared_ptr&lt;foo&gt; ptr_t;

real    0m0.336s
user    0m0.332s
sys     0m0.002s

typedef foo* ptr_t;

real    0m0.006s
user    0m0.002s
sys     0m0.003s


My implementation seems to be running almost as fast as raw pointers, which I think is a good sign.  What worries me here is why Boost is running slower.  Have I missed something in my implementation that is important and I might get into trouble for later?
So the idea behind this is mainly educational...


Cool. Always good to try and understand how things work under the covers.


  ...but I might even consider using it in reality if turns out to be good.


Please rethink this. Smart pointer implementations are incredibly difficult to get right. Scott Myers, of Effective C++ fame, famously tried to implement a shared_ptr. After feedback from something like 10 iterations, it was still wrong.

Let's go through a few things here.

smart_pointer(T* p = NULL)
  : pointer(p), refs(new std::size_t(1))


This constructor should be explicit to avoid implicit type conversions through construction.

Your operator=(T* p) leaks. Here's a small example:

int main()
{
    int *x = new int(5);
    {
        smart_pointer&lt;int&gt; sp(x);
        sp = new int(6);
    } // sp destroyed here 

    std::cout &lt;&lt; *x &lt;&lt; "\n"; // This should have been deleted but wasn't
}


To convince yourself that this is the case, modify your clear() method:

void clear(){
    if (!--*refs){
        std::cout &lt;&lt; "deleteting " &lt;&lt; *pointer &lt;&lt; " at " &lt;&lt; pointer &lt;&lt; "\n";
        delete pointer;
        delete refs;
    }
}


This will print out "deleting 6 at &lt;some memory address&gt;". 

Here's just a small rundown of what boost::shared_ptr (or std::shared_ptr) provides that is missing here:


Constructors allowing a Deleter, which is used instead of a raw delete.
Constructor allowing construction from &lt;template Tp1&gt; shared_ptr(Tp1 * ...) where Tp1 is convertible to type T.
Copy constructor allowing construction from a shared_ptr with convertible template type &lt;T1&gt;. 
Copy constructor taking weak_ptr, unique_ptr.
Move constructor and assignment operator.
Usage of nothrow where it is required to be.
reset, which will replace the currently managed object.
All the non-member operators like operator&lt;, operator==, etc that allow containers and algorithms to work correctly. For example, std::set will not work correctly with your pointer class, neither will things like std::sort. 
A specialization of std::swap.
A specialization of std::hash. Your pointer class won't work correctly with std::unordered_set or std::unordered_map. 
explicit operator bool conversion for nullptr tests, so that one can write if (&lt;some_shared_ptr&gt;) { ... }.
Utility functions like std::make_shared which you should pretty much always use when creating a shared_ptr.


The big pain point, and the reason why boost::shared_ptr or std::shared_ptr will be slower is the fact that they are thread-safe. Your smart_ptr when accessed by multiple threads could very easily delete the pointer it holds before another class is done with it, leading to dereferencing of a deleted object, and thus undefined behaviour. Furthermore, all of the atomic operations are specialized for shared_ptr.

The above is not an exhaustive list.

I don't write this to discourage you, but merely to try and reinforce the fact that writing something like this is a lot of work. It is very technical, and really, really easy to get wrong. In terms of the standard library, shared_ptr may be one of the most difficult things to write correctly.