可能重复:
pimpl: shared_ptr or unique_ptr
smart pointers (boost) explained
有人可以解释shared_ptr和unique_ptr之间的区别吗?
答案 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来跟踪有多少指针引用资源,因此您需要注意不要引入任何引用周期。
简而言之:
unique_ptr
,该对象将在该单个指针被销毁时进行回收。shared_ptr
。希望这有帮助!
答案 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_ptr
和unique_ptr
都设计为按值传递(对唯一指针有明显的可移动性要求)。也不应该让你担心开销,因为他们的力量确实令人震惊,但是如果你有选择的话,更喜欢unique_ptr
,如果你真的需要共同的责任,只能使用shared_ptr
。
答案 2 :(得分:17)
<强>的unique_ptr 强>
是一个智能指针,它只拥有一个对象。
<强> shared_ptr的强>
是共享所有权的智能指针。它是copyable
和movable
。多个智能指针实例可以拥有相同的资源。一旦拥有资源的最后一个智能指针超出范围,资源就会被释放。
答案 3 :(得分:8)
将指针包裹在unique_ptr
中时,您不能拥有unique_ptr
的多个副本。 shared_ptr
包含一个引用计数器,用于计算存储指针的副本数。每次复制shared_ptr
时,此计数器都会递增。每次shared_ptr
被破坏时,该计数器都会递减。当此计数器达到0时,存储的对象将被销毁。