std::shared_ptr initialization: make_shared<Foo>() vs shared_ptr<T>(new Foo) [duplicate]

你离开我真会死。 提交于 2019-11-26 10:21:49

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!