Why is std::unique_ptr reset not the same as assignment?

  • A+

I am trying to understand why

std::unique_ptr<MyClass> p = new MyClass;  

Does not work, but

std::unique_ptr<MyClass> p; p.reset(new MyClass); 

is fine. I somewhat understand how they are different, but I would like to know why the choice was made to make them different. What is the danger in assignment not being the same as reset?

Firstly, std::unique_ptr<MyClass> p = new MyClass; is not assignment, but initialization. And it doesn't work because the constructor of std::unique taking raw pointer is marked as explicit.

explicit unique_ptr( pointer p ) noexcept; (2)

It is declared as explicit to avoid dangerous (unexpected) implicit conversion. e.g.

void foo(std::unique_ptr<int> uptr);  int *rptr = new int; foo(rptr); // suppose rptr is implicitly converted to std::unique_ptr<int>            // then the ownership is passed to the parameter uptr  // when foo() returns uptr is destroyed; the pointer managed by it is deleted too // since rptr has been deleted continue to deference on it leads to UB *rptr = 42; // UB 

Note that explicit constructor is not considered only in copy initialization (e.g. std::unique_ptr<MyClass> p = new MyClass;). You still could use it in direct initialization (e.g. std::unique_ptr<MyClass> p (new MyClass);). And it's used to prohibit implicit conversion, you still could perform explicit conversion. Like the usage of reset, you have to do these things explicitly, to show (and make yourself) that you're pretty sure about what you're doing.

BTW: The assignment from raw pointer doesn't work either, because std::unique_ptr doesn't have overloaded assignment operator taking raw pointer as parameter. For the reason above raw pointer can't be implicitly converted to std::unique_ptr, so the move assignment operator (which takes std::unique_ptr as parameter) won't be considered either.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: