But there's one problem: copy assignment and construction is not allowed.
That is not a problem. If you find it a problem you're doing something wrong.
Even though this restriction serves safety of a programmer, it is quite limiting, too.
It's limiting intentionally, maybe you should reconsider your design.
That's why I created my own wrapper around unique_ptr with copy construction and assignment.
What you want is not a unique_ptr
then, you want a "clone ptr"
This perplexes me
What's perplexing about it? You're trying to create an instance of an abstract base class. Your code would also slice non-abstract bases. It's inherently unsafe.
This should tell you something important: Copying the object held by a unique_ptr
cannot be done generically, it requires context that the unique_ptr
doesn't have. That context either has to come from the object that owns the thing you want to copy (which requires the owning object to know the object's dynamic type) or from the thing you want to copy itself (which can use virtual functions to make a copy in the context of the correct dynamic type.)
A conventional solution is to add a virtual clone()
member function to your types and then use that when possible.
You could incorporate that into your constructor something like this:
template<typename T>
auto clone(T* t) -> decltype(t->clone())
{ return t->clone(); }
template<typename T>
std::unique_ptr<T> clone(T* t, ...)
{ return std::unique_ptr<T>(new T(*t)); }
// ...
_m_opPointerUnique((_m_opPointerUnique == nullptr) ? clone(_m_opPointerUnique.get()) : nullptr)