使用make_shared创建shared_ptr是否有任何缺点

时间:2010-01-27 14:31:18

标签: c++ boost shared-ptr

使用make_shared<T>()而不是使用shared_ptr<T>(new T)是否有任何缺点。

Boost documentation

  

一再提出要求   用户的工厂功能   创建一个给定类型的对象和   返回一个shared_ptr。除了   方便和风格,这样的功能   安全也是例外   因为它可以使用相当快   两者的单一分配   对象及其相应的控制   阻止,消除重大   shared_ptr构造的一部分   高架。这消除了其中一个   关于效率的主要投诉   shared_ptr的。

5 个答案:

答案 0 :(得分:39)

除了@deft_code提供的点之外,还有一个更弱的点:

  • 如果在给定对象的所有weak_ptr已经死亡之后使用shared_ptr s,那么此对象的内存将与控制块一起存在于内存中,直到最后一个weak_ptr死亡。换句话说,对象被销毁但在最后weak_ptr被销毁之前不会被解除分配。

答案 1 :(得分:26)

我至少知道两个。

  • 您必须控制分配。真的不是一个大的,但是一些旧的api喜欢返回你必须删除的指针。
  • 没有自定义删除工具。我不知道为什么不支持,但事实并非如此。这意味着你的共享指针必须使用一个vanilla删除器。

非常弱点。所以尽量使用make_shared。

答案 2 :(得分:14)

来自http://www.codesynthesis.com/~boris/blog/2010/05/24/smart-pointers-in-boost-tr1-cxx-x0/

make_shared()实现的另一个缺点是对象代码大小的增加。由于实现此优化的方式,将为您使用make_shared()的每个对象类型实例化一个额外的虚拟表以及一组虚函数。

答案 3 :(得分:8)

此外, make_shared与工厂模式不兼容。这是因为在工厂函数中对make_shared的调用会调用库代码,而库代码又会调用它无法访问的new ,因为它无法调用类的私有构造函数(s)(如果您正确遵循工厂模式,构造函数应该是私有的。)

答案 4 :(得分:7)

使用make shared,您无法指定如何完成分配 deallocation

如果需要,请改用std::allocate_shared<T>

std::vector<std::shared_ptr<std::string>> avec; 
std::allocator<std::string> aAllocator;
avec.push_back(std::allocate_shared<std::string>(aAllocator,"hi there!"));

请注意,不需要通知向量分配器!

要制作自定义分配器,请查看https://stackoverflow.com/a/542339/1149664