Initializing shared_ptr member variable, new vs make_shared?
Asked Answered
M

2

12

When initializing a shared_ptr member variable:

// .h
class Customer
{
public:
  Customer();

private:
  std::shared_ptr<OtherClass> something_;
}

// .cpp
Customer():
  something_(new OtherClass())
{
}

vs.

Customer():
  something_(std::make_shared<OtherClass>())
{
}

Is the make_shared version allowed? I always seem to see the first version, which is preferred?

Monotheism answered 23/4, 2012 at 23:40 Comment(2)
Herb Sutter just wrote a GOTW on this. See this and also check out one issue that Herb doesn't explicitly state.Bridegroom
@RSamuelKlatchko - An updated link for the first link you provided in your ansewer use herbsutter.com/2013/05/29/gotw-89-solution-smart-pointersMitosis
K
15

The only times when make_shared is not allowed are:

  1. If you're getting a naked pointer allocated by someone else and storing it in shared_ptr. This is often the case when interfacing with C APIs.
  2. If the constructor you want to call is not public (make_shared can only call public constructors). This can happen with factory functions, where you want to force users to create the object from the factory.

    However, there are ways to get around this. Instead of having a private constructor, have a public constructor. But make the constructor take a type with can only be constructed by those with private access to the class. That way, the only people who can call make_shared with that object type are those with private access to the class.

So yes, you can do this.

Kwapong answered 23/4, 2012 at 23:51 Comment(2)
Regarding the friendship issue, is there any mention in the Standard of the particular function to use as friends ? I could well envision some implementation delegating this work to helper functions...Gorman
@MatthieuM.: I was kinda wondering the same thing, which is why I said "may be able". I've asked over at comp.std.c++; we'll see what they have to say about it. If not, I think it might make for a decent defect report.Kwapong
A
5

In this case, using make_shared is not just allowed, but it is better to use it. If you use new, it will allocate memory for your Customer somewhere and then memory for your shared_ptr somewhere else, storing both strong and weak references (for weak pointers and shared pointers). If you use the make_shared you would have only one place in memory with everything and therefore only one new.

I'm not sure that I was really clear, this was the purpose of the GotW #89, read it, it is well explained there.

Aldos answered 25/4, 2012 at 10:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.