Are there any downsides with using make_shared to create a shared_ptr
C++BoostShared PtrC++ Problem Overview
Are there any downsides with using make_shared<T>()
instead of using shared_ptr<T>(new T)
.
Boost documentation states
> There have been repeated requests from > users for a factory function that > creates an object of a given type and > returns a shared_ptr to it. Besides > convenience and style, such a function > is also exception safe and > considerably faster because it can use > a single allocation for both the > object and its corresponding control > block, eliminating a significant > portion of shared_ptr's construction > overhead. This eliminates one of the > major efficiency complaints about > shared_ptr.
C++ Solutions
Solution 1 - C++
In addition to the points presented by @deft_code, an even weaker one:
- If you use
weak_ptr
s that live after all theshared_ptr
s to a given object have died, then this object's memory will live in memory along with the control block until the last weak_ptr dies. In other words the object is destroyed but not deallocated until the lastweak_ptr
is destroyed.
Solution 2 - C++
I know of at least two.
- You must be in control of the allocation. Not a big one really, but some older api's like to return pointers that you must delete.
- No custom deleter. I don't know why this isn't supported, but it isn't. That means your shared pointers have to use a vanilla deleter.
Pretty weak points. so try to always use make_shared.
Solution 3 - C++
From http://www.codesynthesis.com/~boris/blog/2010/05/24/smart-pointers-in-boost-tr1-cxx-x0/
The other drawback of the make_shared() implementation is the increase in the object code size. Due to the way this optimization is implemented, an additional virtual table as well as a set of virtual functions will be instantiated for each object type that you use with make_shared().
Solution 4 - C++
Additionally, make_shared
is not compatible with the factory pattern. This is because the call to make_shared
within your factory function calls the library code, which in turn calls new
, which it doesn't have access to, since it cannot call the class's private constructor(s) (constructor(s) should be private, if you follow the factory pattern correctly).
Solution 5 - C++
With make shared you can not specify how allocation and deallocation of the held object will be done.
When that is desired, use std::allocate_shared<T>
instead:
std::vector<std::shared_ptr<std::string>> avec;
std::allocator<std::string> aAllocator;
avec.push_back(std::allocate_shared<std::string>(aAllocator,"hi there!"));
Note that the vector does not need to be informed about the allocator!
For making a custom allocator, have a look here https://stackoverflow.com/a/542339/1149664