I wrote a class to implement auto_ptr
Assuming you are going to put this in a header file don't do thus

using namespace std;


See: https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice

These should be const as they don't change the state of your auto_ptr

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


The destructor

~auto_ptr()
{
    if(m_p)            // No need to check for NULL
                       // delete on a NULL pointer is valid.
        delete m_p;

    m_p = NULL;        // This is pointless.
                       // The object is about to leave scope.
}   


Why the sudden use of this!

template &lt;typename T&gt;
T* auto_ptr&lt;T&gt;::release()
{
    T* temp = this-&gt;m_p;
          //  ^^^^^^
    this-&gt;m_p = NULL;
 // ^^^^^^
    return temp;
}


Assignment not exception safe.

template &lt;typename T&gt;
auto_ptr&lt;T&gt;&amp; auto_ptr&lt;T&gt;::operator=(auto_ptr&amp; other)
{   
    if(this == &amp;other)
        return *this;

    // This is not exception safe.
    // T is completely unknown to you.
    // Therefore you must assume the person who wrote T is an idiot 
    // and therefore may throw an exception from there destructor.
    delete m_p;

    // If the above statement throws then your object is now in an undefined
    // state with m_p pointing at an invalid object.


    m_p = other.release();
    return *this;
}


The correct way to do this.

template &lt;typename T&gt;
auto_ptr&lt;T&gt;&amp; auto_ptr&lt;T&gt;::operator=(auto_ptr&amp; other)
{   
    if(this == &amp;other)
        return *this;

    auto_ptr&lt;T&gt; tmp = release();
    m_p = other.release();

    // After the state of your (and other objects)
    // are completely defined and are in a good state.
    // then you can tidy up any left over objects.

    return *this;

    // the destructor of tmp should now release it properly.
}