DeepPtr: a deep-copying unique_ptr wrapper in C++ When using the pimple idiom it is necessary to represent your "impl" as a forward declared pointer in the header file.  This necessitates a lot of boilerplate code to implement the rule of five.

Instead, I want to wrap std::unique_ptr with a template class DeepPtr which automatically deep copies on copy construction, assignment, and "deep" swaps on move construction and move assignment.  The resulting class could also be convenient for "value-like" objects that need to be passed by handle due to polymorphism.

Areas of concern are:


Correct use of the swap idiom (should the local swap function be private/public or done some other way)?
Const correctness of the dereferencing operator overloads
Signature of the assignment operator function (const DeepPtr&amp; other) which uses this const ref only to copy to temp.  This seems strange, but correct.
Any other pitfalls that could be caused by this class.




#pragma once
#include &lt;iostream&gt;
#include &lt;memory&gt;

template &lt;typename T&gt;
class DeepPtr
{
public:
    DeepPtr() :myPtr( nullptr ) {}

    DeepPtr( const T&amp; value ) :myPtr( new T{ value } ) {}

    DeepPtr( const DeepPtr&amp; other )
    :myPtr( nullptr )
    {
        if ( other )
        {
            myPtr = std::unique_ptr&lt;T&gt;{ new T{ *other } };
        }
    }

    DeepPtr( DeepPtr&amp;&amp; other )
    :myPtr( nullptr )
    {
        if ( other )
        {
            myPtr = std::unique_ptr&lt;T&gt;{ new T{ *other } };
        }
    }

    DeepPtr&amp; operator=( const DeepPtr&amp; other )
    {
        DeepPtr temp{ other };
        swap( *this, temp );
        return *this;
    }

    DeepPtr&amp; operator=( DeepPtr&amp;&amp; other )
    {
        swap( *this, other );
        return *this;
    }

    static void swap( DeepPtr&amp; left, DeepPtr&amp; right ) { std::swap( left.myPtr, right.myPtr ); }

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

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

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

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

    const T* const get() const { return myPtr.get(); }

    operator bool() const { return (bool)myPtr; }

private:
    std::unique_ptr&lt;T&gt; myPtr;
};
You already accepted Loki's answer (and he made good points) but there is one comment I wanted to add regarding this:


  •Any other pitfalls that could be caused by this class.


Your class has no information on the concrete type held within, causing slicing in the presence of derived classes;

Consider this scenario:

class Base { ... }; // not abstract (can be instantiated)
class Derived: public Base { ... };

auto ptr1 = DeepPtr&lt;Base&gt;(new Derived{});
auto ptr2 = ptr1;


The last line will populate ptr2 with a Base instance that has all the sliced values from ptr2's Derived instance (because ptr2's constructorr calls new T, which resolves to new Base - not new Derived).

You have two possible solutions for this:


intrusive cloning (your class hierarchy rooted in Base needs to implement a virtual Base* clone() = 0 where each specialization of Base returns it's own instance); this cloning implementation would be then used for deep copy;
transparent cloning, based on template specialization of a factory function, by the derived type. I needed to implement something similar for the same reason (deep copy of polymorphic pointers). You can see here my implementation.

See the use of to_polymorphic functions in my question, and how they instantiate the correct cloning function, transparently.