simple shared pointer implementation in single threaded environment Update: The code below has some obvious problems, and it is not allowed to revise code in the original question, so I have to post a new question, the revised code is here.

std::shared_ptr has the potential problem that two pointer point to the same object but to different control blocks. And its atomic operation is pure overhead in a single threaded environment. So I wrote the following version to avoid these problems. This implementation also has the advantage that an empty pointer is the same size as a void *.

template &lt;typename T&gt;
struct ThreadUnsafeSharedPtr {

private:
    struct Pair {
        T data;
        size_t cnt;
        template &lt;typename ... Args&gt;
        Pair(Args &amp;&amp; ... args): data(std::forward&lt;Args&gt;(args)...), cnt(1) {}
    };
    Pair *ptr;

public:
    template &lt;typename ... Args&gt;
    static ThreadUnsafeSharedPtr make(Args &amp;&amp; ... args) {
        ThreadUnsafeSharedPtr p;
        p.ptr = new Pair(std::forward&lt;Args&gt;(args)...);
        return p;
    }

    ThreadUnsafeSharedPtr() : ptr(nullptr) {}

    ThreadUnsafeSharedPtr(const ThreadUnsafeSharedPtr &amp; other) : ptr(other.ptr) {
        if (ptr &amp;&amp; &amp;other != this) {
            ++(ptr-&gt;cnt);
        }
    }
    ThreadUnsafeSharedPtr &amp; operator=(const ThreadUnsafeSharedPtr &amp; other) {
        ptr = other.ptr;
        if (ptr &amp;&amp; &amp;other != this) {
            ++(ptr-&gt;cnt);
        }
        return *this;
    }
    ThreadUnsafeSharedPtr(ThreadUnsafeSharedPtr &amp;&amp; other) : ptr(other.ptr) {
        if (&amp;other != this) {
            other.ptr = nullptr;
        }
    }
    ThreadUnsafeSharedPtr &amp; operator=(ThreadUnsafeSharedPtr &amp;&amp; other) {
        if (&amp;other != this) {
            ptr = other.ptr;
            other.ptr = nullptr;
        }
        return *this;
    }

    ~ThreadUnsafeSharedPtr() {
        if (ptr) {
            if(--ptr-&gt;cnt == 0) {
                delete ptr;
            }
        }
    }
};
Your implementation misses to implement pointer semantics in the form of an overloaded operator-&gt;() and operator*().

Isn't that the whole point of a pointer surrogate?