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?
One reason is because make_shared allocates the reference count together with the object to be managed in the same block of memory. OK, I got the point. This is of course more efficient than two separate allocation operations.
std::make_shared Allocates and constructs an object of type T passing args to its constructor, and returns an object of type shared_ptr<T> that owns and stores a pointer to it (with a use count of 1). This function uses ::new to allocate storage for the object.
A null shared_ptr does serve the same purpose as a raw null pointer. It might indicate the non-availability of data. However, for the most part, there is no reason for a null shared_ptr to possess a control block or a managed nullptr .
So, we should use shared_ptr when we want to assign one raw pointer to multiple owners. // referring to the same managed object. When to use shared_ptr? Use shared_ptr if you want to share ownership of a resource.
The only times when make_shared
is not allowed are:
shared_ptr
. This is often the case when interfacing with C APIs.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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With