创建共享指针的首选方式
Preferred way of creating shared pointers
documentation 指出 std::make_shared<T>
通常会同时为 T
和智能指针的控制块分配内存,而 std::shared_pointer<T>(new T)
则执行两次分配。这是否意味着它更有效,因此如果可能,应该始终使用 std::make_shared
?
关于 Qt 等效项的相同问题 - QSharedPointer
。根据 docs,QSharedPointer
内部结构和对象在单个内存分配中进行分配,这有助于减少 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_ptr
与 std::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}
.
documentation 指出 std::make_shared<T>
通常会同时为 T
和智能指针的控制块分配内存,而 std::shared_pointer<T>(new T)
则执行两次分配。这是否意味着它更有效,因此如果可能,应该始终使用 std::make_shared
?
关于 Qt 等效项的相同问题 - QSharedPointer
。根据 docs,QSharedPointer
内部结构和对象在单个内存分配中进行分配,这有助于减少 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_ptr
与 std::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}
.