shared_ptr和scoped_ptr比较

38

scoped_ptr不可复制,并在作用域外被删除。因此,它有点像受限制的shared_ptr。所以似乎除非确实需要限制复制操作,否则最好使用shared_ptr。因为有时你不知道是否需要创建对象的副本。那么问题是:除了上面提到的情况,我们是否可以认为shared_ptr更好(或建议)使用而不是scoped_ptrscoped_ptrshared_ptr快得多吗?或者它有优势吗?

谢谢!

5个回答

72

shared_ptrscoped_ptr更加沉重。它需要分配和释放一个引用计数对象以及受控对象,并处理线程安全的引用计数 - 在我工作的某个平台上,这是一个显著的开销。

我的建议(通常情况下)是使用最简单的对象来满足您的需求。如果您需要引用计数共享,请使用shared_ptr; 如果您只需要在使用单个引用后自动删除,请使用scoped_ptr


16
Mike,我非常赞同。我总是建议人们从boost::scoped_ptr开始。如果需要转移所有权语义(保持单一所有权),则“升级”到std::auto_ptr。仅当需要共享所有权时才使用boost::shared_ptr。此外,Boost.ptr_container库是boost::shared_ptr容器的一个不错选择,当元素实际上不需要共享时。 - David Joyner
2
顺便提一下:如果确实需要共享指针,您可以使用make_sharedallocate_shared来分配对象,而不是使用new,以消除额外的分配。 - Mike Seymour
17
@David:我大部分都同意,但我会完全跳过auto_ptr。它不能在标准容器中安全使用,所以如果你不是真的小心,它很可能会带来一些令人不快的惊喜。 - jalf
1
同意,特别是自从C++11以来auto_ptr已经被弃用,不应该推荐使用,我会提到unique_ptr。 - Kit10

16

性能 - shared_ptr 提供了更多的功能,但也需要额外的分配(它也更大,但这很少重要)。

[编辑]可以通过使用make_shared避免第二次分配,但是weak_ptr将在对象销毁后仍然持有整个分配,这可能对大型对象造成问题。

意图表达 使用scoped_ptr,您更明确地表达了您想要做什么。(如果您想知道-这是一件好事 :))。如果您正确地执行此操作,shared_ptr也将指示“此对象旨在超出此范围存活”


3
+1 表示有意愿。在这方面,scoped_ptrshared_ptr 非常清晰易懂。同样,使用 std::auto_ptr 应该表明您愿意在某个时刻转移对象的所有权。 - David Joyner

6

它们的预期目的不同,因此,在许多情况下,“shared_ptr vs scoped_ptr”根本不是一个问题。当你只需要一个scoped_ptr时,你可以使用shared_ptr。但是这样做有什么意义呢?由于涉及所有引用计数,因此shared_ptr可能具有稍大的开销。


3

scoped_ptrshared_ptr 快得多。这是正确的。 shared_ptr 总是使用你的分配器或默认分配器来分配内存。


1

Scoped_ptr与shared_ptr、weak_ptr或unique_ptr几乎没有任何共同之处,因为它只是在做“引用计数”的非常特殊的情况。在设计良好的代码中,您通常不需要它,但拥有这个工具是很好的。

基本上,scoped_ptr根本不是一个引用计数的东西。相反,它是一个您在堆栈上创建的对象(在局部作用域内),以便您可以执行以下操作:

  //Some enclosing scope- anything set off by "{}" or even a function:
   {
       scoped_ptr<MyObject> ptr = new MyObject( parameters...);
   } // When we hit this closing brace, "ptr" will delete the "MyObject" inside.

您会在互斥锁和其他同步原语中更多地看到这种模式-我可以声明一个“AutoLock”,它将锁定传递给它的互斥锁,然后在删除时解锁它,以将整个“{}”范围转换为临界区。
另请注意,“scoped_ptr”只有在某些情况下无法进行普通的堆栈分配,例如“MyObject obj(params..)”时才有意义。毕竟,它所做的就是让您像使用堆栈上的对象一样使用堆分配的对象。这往往是比shared_ptr及其姊妹的引用计数更少见的用例。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接