问题
This question already has an answer here:
- Difference in make_shared and normal shared_ptr in C++ 8 answers
What\'s the difference between:
std::shared_ptr<int> p = std::shared_ptr<int>( new int );
and
std::shared_ptr<int> p = std::make_shared< int >();
?
Which one should I prefer and why?
P. S. Pretty sure this must have been answered already, but I can\'t find a similar question.
回答1:
Both examples are rather more verbose than necessary:
std::shared_ptr<int> p(new int); // or '=shared_ptr<int>(new int)' if you insist
auto p = std::make_shared<int>(); // or 'std::shared_ptr<int> p' if you insist
What's the difference?
The main difference is that the first requires two memory allocations: one for the managed object (new int
), and one for the reference count. make_shared
should allocate a single block of memory, and create both in that.
Which one should I prefer and why?
You should usually use make_shared
as it's more efficient. As noted in another answer, it also avoids any possibility of a memory leak, since you never have a raw pointer to the managed object.
However, as noted in the comments, it has a potential disadvantage that the memory won't be released when the object is destroyed, if there are still weak pointers preventing the shared count from being deleted.
回答2:
From en.cppreference.com
In contrast, the declaration std::shared_ptr<T> p(new T(Args...))
performs at least two memory allocations, which may incur unnecessary overhead.
Moreover, f(shared_ptr<int>(new int(42)), g())
can lead to memory leak if g throws an exception. This problem doesn't exist if make_shared is used.
So I would recommend the make_shared
approach if possible.
回答3:
Be aware that make_shared
limits you to using the default allocation/deallocation functions so if you want to have more control, make_shared
is not an option. In other words, something like
std::shared_ptr<uint8_t>(p, [](uint8_t *p){ /*user code */});
is impossible using make_shared
. One could use allocate_shared
instead, but only the allocator can be specified, not a deleter. Sometimes one need to control allocation and deletion of the wrapped class.
来源:https://stackoverflow.com/questions/18301511/stdshared-ptr-initialization-make-sharedfoo-vs-shared-ptrtnew-foo