Home > database >  Why doesn't std::unique_ptr allow itself to be copyable?
Why doesn't std::unique_ptr allow itself to be copyable?

Time:07-08

I know that it is to prevent two copies of unique_ptr to have a possible dangling pointer where the pointed-to object could have been already deallocated and stuff like that. But why didn't they decide to allow a kind of deep copy, where instead of just copying pointers they allocate new memory and delegate the copy to the template argument type of unique_ptr.

CodePudding user response:

The main problem is that just blindly calling the template argument's copy ctor with new will slice the object if it is actually a subclass, making this a very unsafe thing to do in general.

That said, I've found it useful to extend unique_ptr:

template<class T, class D = std::default_delete<T>>
class autoclone_ptr : public std::unique_ptr<T, D> {
 public:
    autoclone_ptr() = default;
    autoclone_ptr(autoclone_ptr &&) = default;
    autoclone_ptr &operator=(autoclone_ptr &&) = default;
    autoclone_ptr(const autoclone_ptr &a) : std::unique_ptr<T,D>(a ? a->clone() : nullptr) {}
    autoclone_ptr &operator=(const autoclone_ptr &a) {
        auto *t = a.get();
        this->reset(t ? t->clone() : nullptr);
        return *this; }
};

This can only be instantiated for classes that define a clone() method to avoid slicing problems.

CodePudding user response:

It would be confusing to implicitly make a deep copy when copying a pointer. By making it neither Copy Constructible nor Copy Assignable you are forced to make a conscious decision.

In order to call the copy constructor you have to use make_unique: Why std::make_unique calls copy constructor. It will copy the old values to new memory.

  • Related