-1

I see that std::unique_ptr has the following ways of initialization:

std::unique_ptr<some_class> sc_ptr{ new some_class };

wherein someone could delete the allocated some_class from underneath the std::unique_ptr.

and

some_class *scptr { new some_class }
std::unique_ptr<some_class> sc_ptr1{ scptr };
std::unique_ptr<some_class> sc_ptr2{ scptr };

Defeating the purpose of 'unique' in the std::unique_ptr and also leading to UDB.

Now the question that I have is: Why does the std::unique_ptr class even allow above methods of initialization while it has the std::make_unique<some_class>() method at its disposal?

Am I missing something here?

Abhishek A Udupa
  • 401
  • 6
  • 13
  • 2
    How else would you construct a `unique_ptr` from a raw pointer? c++ provides you the tools to implement programs, if you choose to use those tools to shoot yourself in the foot the language won't prevent you from doing so – Alan Birtles May 09 '20 at 17:17
  • 2
    Also, it's partly for backwards compatibility. `std::make_unique` was not available until C++14 so there will be a lot of programs out there that could make use of it but don't. – Paul Sanders May 09 '20 at 17:18
  • @AlanBirtles `std::make_unique` initializes using a raw pointer under the hood doesn't it? – Abhishek A Udupa May 09 '20 at 17:25
  • @PaulSanders that was something I didn't know. Thanks! – Abhishek A Udupa May 09 '20 at 17:26
  • @AbhishekAUdupa yes, unlike [`std::make_shared`](https://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared), [`std::make_unique`](https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique) is a simple wrapper around the constructor and has no performance benefit – Alan Birtles May 09 '20 at 17:27

1 Answers1

1

Several reasons:

  1. make_unique takes custom deleter, so it is supposed to handle custom allocation. Passing allocator to a hypothetical allocate_unique is cumbersome.
  2. The same as .release() can provide a junction with a code that manages lifetime differently (including API in C interface that use raw pointers).
  3. Historical reasons, make_unique was only introduced in C++14.

Note also that starting C++17 the main reason to prefer make_unique over new was removed, so you may see make_unique only as a syntax sugar, not as exception safety utility. See Why use std::make_unique in C++17?

Alex Guteniev
  • 12,039
  • 2
  • 34
  • 79