1

Say if I have this definition:

class A
{
    A();
    std::unique_ptr<B> m_b;   
};

class B {};

Is there a difference if I initialize A like:

A::A() : m_b(new B()) {}

vs.

A::A() : m_b(std::make_unique<B>()) {}

Additionally for the first case, can i be sure that I do not have to call delete explicitly?

Jarod42
  • 173,454
  • 13
  • 146
  • 250
John Tan
  • 1,217
  • 12
  • 30
  • 1
    `make_unique` takes the arguments for constructing a `B`, not an object of `B`, so in your case it should be `A::A() : m_b(std::make_unique()) {}` – mch May 28 '20 at 09:29
  • This has been closed as duplicate, but it discusses not the general merits of using make_unique over new, but focuses on the special case of using it in member initializer lists. This particular case has not been explicitly addressed in either of https://stackoverflow.com/q/37514509/5747415, https://stackoverflow.com/q/22571202/5747415, https://herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/, https://herbsutter.com/gotw/_102/. The benefits of make_unique that are listed for all the other scenarios do not seem to apply in this case. – Dirk Herrmann Sep 25 '20 at 19:16

1 Answers1

1

The only difference is style. Since use of operator new is now considered old fashioned std::make_unique is recommended.

For compiler there is no difference.

By the way is should be:

A::A() : m_b{std::make_unique<B>()} {}

Also see CppCoreGuidelines/CppCoreGuidelines.md at master · isocpp/CppCoreGuidelines

C.150: Use make_unique() to construct objects owned by unique_ptrs

Reason

make_unique gives a more concise statement of the construction. It also ensures exception safety in complex expressions.

Example
unique_ptr<Foo> p {new Foo{7}};    // OK: but repetitive

auto q = make_unique<Foo>(7);      // Better: no repetition of Foo

// Not exception-safe: the compiler may interleave the computations of arguments as follows:
//
// 1. allocate memory for Foo,
// 2. construct Foo,
// 3. call bar,
// 4. construct unique_ptr<Foo>.
//
// If bar throws, Foo will not be destroyed, and the memory-allocated for it will leak.
f(unique_ptr<Foo>(new Foo()), bar());

// Exception-safe: calls to functions are never interleaved.
f(make_unique<Foo>(), bar());
Marek R
  • 23,155
  • 5
  • 37
  • 107