创建共享指针的首选方式

Preferred way of creating shared pointers

documentation 指出 std::make_shared<T> 通常会同时为 T 和智能指针的控制块分配内存,而 std::shared_pointer<T>(new T) 则执行两次分配。这是否意味着它更有效,因此如果可能,应该始终使用 std::make_shared

关于 Qt 等效项的相同问题 - QSharedPointer。根据 docsQSharedPointer 内部结构和对象在单个内存分配中进行分配,这有助于减少 long-运行 应用程序中的内存碎片。这是否意味着 QSharedPointer<T>::create() 是首选?

class MyClass {};

QSharedPointer<MyClass> ptr1 = QSharedPointer<MyClass>::create();   // better
QSharedPointer<MyClass> ptr2(new MyClass);  // worse

std::make_shared 几乎在所有情况下都是首选。但是,如果您使用弱指针,您很容易陷入 "memory leak" 的情况,即内存保持的时间比您第一眼看到的要长得多(在所有 shared_ptr 都消失之后)。

只要 std::weak_ptrstd::shared_ptr 控制块相关联,控制块就必须保留。由于 std::make_shared 为控制块和数据创建了一个内存分配,如果控制块保留,数据也必须保留。使用std::shared_ptr,有两个分配,所以它们可以独立清理。

因此,如果您不使用 std::weak_ptr(下面的附加警告),绝对总是首选 std::make_shared 以获得包括分配数量和异常安全性在内的好处。如果您正在使用 std::weak_ptr,您的设计一定要考虑周到得多。

Modern Effective C++第4章专门how/when使用不同的智能指针。这是一本简明的书,供现有的 c++ 程序员了解 c++11/14 中的新功能,包括智能指针。

编辑:正如@midor 提到的,您在使用 std::make_shared 时也根本没有提供自定义删除器的选项。此外,如果类型 T 有不同的构造函数,可以用相同的类型调用,但一个用 (),一个用 {},那么它总是喜欢用 () 的那个。例如 std::make_shared<std::vector>(10,10) 调用 std::vector(10,10) 而不是 std::vector{10,10}.