2012-01-12 36 views
15

我想不出任何情况下当构建对象时有没有任何理由不使用std :: make_shared?

std::shared_ptr<Object> obj(new Object("foo", 1)); 

将是首选,以

auto obj = std::make_shared<Object>("foo", 1); 

后者总是带来更好的地方,并减少内存碎片。是否有任何情况,您希望(或被迫)使用第一种形式,除了与返回原始指针的代码进行交互?

+4

我想,你会考虑从'std :: unique_ptr '转换为与原始指针接口?因为我认为这是从工厂函数返回的规范类型。其他指针会被认为是“原始指针”,毕竟在现代C++中占有一席之地? – 2012-01-12 23:18:06

回答

18

后者总是会导致更好的局部性并减少内存碎片。

不是总是。我们鼓励实现为引用计数对象和引用计数使用单个分配,但这不是需要才能这样做。

为什么你不想使用std::make_shared?考虑一下你有一个大的动态分配对象的情况,你想拥有std::shared_ptr,并且你知道这个对象的弱引用可能会超过对这个对象的强引用(也许有很多弱引用并且只有一个或两个短命的强有力的参考)。

在这种情况下,std::make_shared将是一个糟糕的选择,假设它分配一个同时拥有对象和引用计数的块:分配的块(这很大,记住)不能被销毁,直到没有强或对象留下的弱引用。

如果您要自己动态分配对象并将指针传递给std::shared_ptr构造函数,则只要没有强引用,即使仍存在弱引用,对象占用的内存也会被释放。

+0

这是一个很好的观点。现在我想到了,引用计数与对象的合并也可能导致错误共享,这可能会影响多线程场景中的性能。 – 2012-01-13 00:21:26

0

如果您构建的对象将在对象的生命周期中共享多个实体,那么是的,您希望尽可能使用std :: make_shared。有些地方可能无法获得别人的指针,例如,一个工厂可能会返回一个原始指针或一个你想存储在shared_ptr中的std :: unique_ptr,从而阻止使用make_shared。

标题中的问题有点不同;有很多理由你可能不想为你的对象使用shared_ptr。如果生命期实际上由多个对象共享,则只应使用shared_ptr。否则,更喜欢堆栈分配对象或使用unique_ptr。

0

现代IDE具有“查找使用”功能。如果使用std::make_shared构造对象,则当您搜索调用该对象的构造函数的位置时,IDE将不会显示使用std::make_shared的位置。

相关问题