There's a couple of reasons for this.
The first has to do with a bit of C++ history. Prior to C++17, there was no exception safety with the constructor, so doing the following:
some_func(std::unique_ptr<T1>(), std::unique_ptr<T2>())
would leak memory were the constructor for T1 to throw an exception, as the C++ standard did not require that, in this case the first unique_ptr, should have it's memory deallocated. This is no longer the case since C++17
Second, it allows for a more general rule of "never to use new
" which without make_unique
would be "never use new
except for when using unique_ptr
or shared_ptr
"
Also there's the added bonus of no redundant typing, as with the constructor you have to do:
auto p = std::unique_ptr<T>(new T());
listing T
twice, which can be particularly ugly in the case of long type names. With make_unique
this shortens to
auto p = std::make_unique<T>();
(p1);`. Is this creating a `unique_ptr` to manage the existing `p1`? Or is this creating a `unique_ptr` to create a new `S` which has the `p1` as its parent?– Raymond Chen Oct 16 '21 at 14:23