std :: shared_ptr初始化:make_shared <foo>()vs shared_ptr <t>(new Foo)</t> </foo>

时间:2013-08-18 16:56:37

标签: c++ c++11 shared-ptr smart-pointers

有什么区别:

std::shared_ptr<int> p = std::shared_ptr<int>( new int );

std::shared_ptr<int> p = std::make_shared< int >();

我应该选择哪一个?为什么?

P上。 S.很确定这已经得到了解答,但我找不到类似的问题。

3 个答案:

答案 0 :(得分:55)

这两个例子都比必要的更冗长:

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
  

有什么区别?

主要区别在于第一个需要两个内存分配:一个用于托管对象(new int),另一个用于引用计数。 make_shared应该分配一个内存块,并在其中创建。

  

我应该选择哪一个?为什么?

您通常应该使用make_shared,因为它更有效率。正如另一个答案所述,它也避免了任何内存泄漏的可能性,因为你从来没有一个指向托管对象的原始指针。

然而,正如评论中所指出的,它有一个潜在的缺点,即如果仍有弱指针阻止共享计数被删除,则在销毁对象时不会释放内存。

答案 1 :(得分:14)

来自en.cppreference.com

相反,声明std::shared_ptr<T> p(new T(Args...)) 至少执行两次内存分配,这可能会产生不必要的开销。

此外,如果g抛出异常,f(shared_ptr<int>(new int(42)), g()) 会导致内存泄漏。如果使用make_shared,则不存在此问题。

因此,如果可能的话,我会推荐make_shared方法。

答案 2 :(得分:9)

请注意make_shared限制您使用默认分配/取消分配功能,因此如果您想要更多控制权,make_shared不是一个选项。换句话说,像是

std::shared_ptr<uint8_t>(p, [](uint8_t *p){ /*user code */}); 
使用make_shared

是不可能的。可以使用allocate_shared代替,但只能指定分配器,而不能指定删除器。有时需要控制包装类的分配和删除。