I came across this post and one of the answers by @kerek SB states
std::shared_ptr<Object> p1 = std::make_shared<Object>("foo"); std::shared_ptr<Object> p2(new Object("foo"));
In your code, the second variable is just a naked pointer, not a shared pointer at all.
Now on the meat. make_shared is (in practice) more efficient, because it allocates the reference control block together with the actual object in one single dynamic allocation. By contrast, the constructor for shared_ptr that takes a naked object pointer must allocate another dynamic variable for the reference count. The trade-off is that make_shared (or its cousin allocate_shared) does not allow you to specify a custom deleter, since the allocation is performed by the allocator.
(This does not affect the construction of the object itself. From Object's perspective there is no difference between the two versions. What's more efficient is the shared pointer itself, not the managed object.)
Now I have two questions regarding this post and would appreciate it if someone could clarify this
Why is the second one not a shared pointer ? Will that not increment a reference count
How does make_shared only make one memory allocation and new makes two thus making make_shared more efficent ?
A little clarification on this would be appreciated.
The code referred to as the second variable is in fact this (taken from OP's code):
This does not create a
std::shared_ptr
, it creates a pointer toObject
.When creating a
std::shared_ptr
using its constructor that takes a naked pointer, you must pass a pointer to already allocated memory (e.g. allocated usingnew
). This means that the memory for the object has already been allocated when creating thestd::shared_ptr
object itself. Thestd::shared_ptr
needs to allocate memory for its own workings, like e.g. a reference counter. So there are 2 allocations: the one usingnew
passed to the ctor ofstd::shared_ptr
and the one required when constructing thestd::shared_ptr
itself.The helper function
std::make_shared
uses only 1 allocation as you pass it the arguments needed to construct the object, not a pointer to the object itself.std::make_shared
can then allocate memory once that holds both the object and the ref counter.