unique_ptr和shared_ptr之间的差异

时间:2011-07-29 17:26:00

标签: c++ pointers c++11 shared-ptr unique-ptr

  

可能重复:
  pimpl: shared_ptr or unique_ptr
  smart pointers (boost) explained

有人可以解释shared_ptr和unique_ptr之间的区别吗?

4 个答案:

答案 0 :(得分:431)

这两个类都是智能指针,这意味着它们会自动(在大多数情况下)释放它们在无法再引用该对象时指向的对象。两者之间的区别在于每种类型的指针有多少可以引用资源。

使用unique_ptr时,最多只能有一个unique_ptr指向任何一个资源。当销毁unique_ptr时,资源会自动回收。因为任何资源只能有一个unique_ptr,所以任何复制unique_ptr的尝试都会导致编译时错误。例如,此代码是非法的:

unique_ptr<T> myPtr(new T);       // Okay
unique_ptr<T> myOtherPtr = myPtr; // Error: Can't copy unique_ptr

但是,unique_ptr可以移动使用新的移动语义:

unique_ptr<T> myPtr(new T);                  // Okay
unique_ptr<T> myOtherPtr = std::move(myPtr); // Okay, resource now stored in myOtherPtr

同样,你可以这样做:

unique_ptr<T> MyFunction() {
    unique_ptr<T> myPtr(/* ... */);

    /* ... */

    return myPtr;
}

这个成语意味着“我正在向您返回托管资源。如果您没有明确捕获返回值,那么资源将被清除。如果您这样做,那么您现在拥有该资源的独占所有权。 “通过这种方式,您可以将unique_ptr视为auto_ptr的更安全,更好的替代品。

另一方面,

shared_ptr允许多个指针指向给定资源。当资源的最后shared_ptr被销毁时,资源将被释放。例如,此代码完全合法:

shared_ptr<T> myPtr(new T);       // Okay
shared_ptr<T> myOtherPtr = myPtr; // Sure!  Now have two pointers to the resource.

在内部,shared_ptr使用reference counting来跟踪有多少指针引用资源,因此您需要注意不要引入任何引用周期。

简而言之:

  1. 当您想要一个指向对象的单个指针时,请使用unique_ptr,该对象将在该单个指针被销毁时进行回收。
  2. 如果需要指向同一资源的多个指针,请使用shared_ptr
  3. 希望这有帮助!

答案 1 :(得分:69)

unique_ptr是轻量级智能指针,如果你只有一个动态对象,一个消费者具有唯一(因此“独特”)的责任 - 也许是一个包装器需要维护一些动态分配对象的类。 unique_ptr的开销很小。它不可复制,但可移动。其类型template <typename D, typename Deleter> class unique_ptr;,因此它取决于两个模板参数。

unique_ptr也是auto_ptr想要在旧版C ++中使用的内容,但由于该语言的限制而无法实现。

另一方面,

shared_ptr是一种非常不同的动物。显而易见的区别在于,您可以让许多消费者共同负责动态对象(因此“共享”),并且只有在所有共享指针消失后才会销毁该对象。此外,您可以观察弱指针,如果他们关注的共享指针消失,将会智能地通知它。

在内部,shared_ptr还有更多内容:有一个引用计数,它以原子方式更新以允许在并发代码中使用。此外,还有大量的分配,一个用于内部簿记“参考控制块”,另一个(通常)用于实际的成员对象。

但是还有另一个很大的区别:共享指针类型总是 template <typename T> class shared_ptr;,尽管你可以使用自定义删除器来初始化它使用自定义分配器。使用类型擦除和虚函数调度来跟踪删除和分配器,这会增加类的内部权重,但具有巨大的优势,即T类型的不同种类的共享指针都是兼容的,无论删除和分配细节。因此,他们真正表达了“T共同责任”的概念,而不会给消费者带来细节上的负担!

shared_ptrunique_ptr都设计为按值传递(对唯一指针有明显的可移动性要求)。也不应该让你担心开销,因为他们的力量确实令人震惊,但是如果你有选择的话,更喜欢unique_ptr,如果你真的需要共同的责任,只能使用shared_ptr

答案 2 :(得分:17)

<强>的unique_ptr
是一个智能指针,它只拥有一个对象。

<强> shared_ptr的
是共享所有权的智能指针。它是copyablemovable。多个智能指针实例可以拥有相同的资源。一旦拥有资源的最后一个智能指针超出范围,资源就会被释放。

答案 3 :(得分:8)

将指针包裹在unique_ptr中时,您不能拥有unique_ptr的多个副本。 shared_ptr包含一个引用计数器,用于计算存储指针的副本数。每次复制shared_ptr时,此计数器都会递增。每次shared_ptr被破坏时,该计数器都会递减。当此计数器达到0时,存储的对象将被销毁。