使用make_shared创buildshared_ptr有什么缺点吗?
使用make_shared<T>()
而不是使用shared_ptr<T>(new T)
有什么缺点make_shared<T>()
?
提升文档状态
用户反复请求一个工厂函数,该函数创build一个给定types的对象并返回一个shared_ptr给它。 除了方便和风格之外,这样的函数也是exception安全的,速度也相当快,因为它可以为对象和相应的控制块使用一个单独的分配,消除了shared_ptr构造开销的重要部分。 这消除了关于shared_ptr的主要效率投诉之一。
我知道至less有两个。
- 你必须控制分配。 不是一个真正的大,但一些较老的API喜欢返回指针,你必须删除。
- 没有自定义删除。 我不知道为什么这不被支持,但事实并非如此。 这意味着你的共享指针必须使用一个香草删除器。
相当薄弱的一点。 所以尽量总是使用make_shared。
除了@deft_code提供的点外,还有一个更弱的点:
- 如果在所有
shared_ptr
到达给定对象的时候使用了weak_ptr
,那么这个对象的内存将和控制块一起存在内存中,直到最后一个weak_ptr死亡。 换句话说,对象被销毁,但不会被释放,直到最后一个weak_ptr
被销毁。
来自http://www.codesynthesis.com/~boris/blog/2010/05/24/smart-pointers-in-boost-tr1-cxx-x0/
make_shared()实现的另一个缺点是目标代码大小的增加。 由于这种优化的实现方式,将为每个使用make_shared()的对象types实例化一个附加的虚拟表以及一组虚拟函数。
另外, make_shared
与工厂模式不兼容 。 这是因为在你的工厂函数中调用make_shared
调用了库代码,库代码又调用了new
,它不能访问的新的, 因为它不能调用类的私有构造函数 (构造函数应该是私有的,如果你按照正确的工厂模式)。
通过make共享,您不能指定如何分配和取消分配所持有的对象。
当需要的时候,使用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