Tra*_*cer 26 c++ smart-pointers make-shared c++11
我感兴趣的是这两行代码是否相同:
shared_ptr<int> sp(new int(1)); // double allocation?
shared_ptr<int> sp(make_shared<int>(1)); // just one allocation?
Run Code Online (Sandbox Code Playgroud)
如果这是真的,有人可以解释为什么在第二行只有一个分配?
Sha*_*our 33
第一种情况下不执行双重分配,它执行两个分配,一个用于管理对象和一个用于控制块的shared_ptr
.
对于第二种情况,cppreference有一个很好的解释为什么std :: make_shared 通常只执行一个内存分配(强调我的前进):
此函数通常使用单个内存分配为T对象和shared_ptr的控制块分配内存(它是标准中的非绑定要求).相反,声明std :: shared_ptr p(new T(Args ...))执行至少两次内存分配,这可能会产生不必要的开销.
并从std :: shared_ptr部分说:
当通过调用std :: make_shared或std :: allocate_shared创建shared_ptr时,将使用单个分配创建控制块和托管对象的内存.托管对象在控制块的数据成员中就地构造.当通过其中一个shared_ptr构造函数创建shared_ptr时,必须单独分配托管对象和控制块.在这种情况下,控制块存储指向被管理对象的指针.
此make_shared
描述与C++ 11草案标准一致,该标准在shared_ptr创建部分中说明20.7.2.2.6
Run Code Online (Sandbox Code Playgroud)template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args); template<class T, class A, class... Args> shared_ptr<T> allocate_shared(const A& a, Args&&... args);
[...]
备注:实现应该只执行一次内存分配.[注意:这提供的效率相当于侵入式智能指针. - 尾注]
[注意:这些函数通常会分配比sizeof(T)更多的内存,以允许内部簿记结构,例如引用计数. - 尾注]
Herb Sutter make_shared
对GotW#89解决方案中使用的优势有更详细的解释:智能指针并指出了一些优点:
请注意,使用make_shared使用std :: weak_ptr时 有一些缺点.
节中cppreference std::shared_ptr的解释Implementation notes
在典型的实现中,std::shared_ptr 仅保存两个指针:
- 指向被管理对象的指针
- 指向控制块的指针
当通过调用 std::make_shared 或 std::allocate_shared 创建shared_ptr时,控制块和托管对象的内存都是通过单个分配创建的。管理对象在控制块的数据成员中就地构建。当通过shared_ptr构造函数之一创建shared_ptr时,必须单独分配托管对象和控制块。在这种情况下,控制块存储指向被管理对象的指针。