有什么区别:
std::shared_ptr<int> p = std::shared_ptr<int>( new int );
和
std::shared_ptr<int> p = std::make_shared< int >();
我应该选择哪一个?为什么?
P上。 S.很确定这已经得到了解答,但我找不到类似的问题。
答案 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)
相反,声明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
代替,但只能指定分配器,而不能指定删除器。有时需要控制包装类的分配和删除。