为了账号安全,请及时绑定邮箱和手机立即绑定

unique_ptr和shared_ptr之间的差异

unique_ptr和shared_ptr之间的差异

C++
Qyouu 2019-08-23 15:43:24
unique_ptr和shared_ptr之间的差异有人可以解释shared_ptr和unique_ptr之间的差异吗?
查看完整描述

3 回答

?
心有法竹

TA贡献1866条经验 获得超5个赞

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


使用时unique_ptr,最多只能unique_ptr指向一个资源。当它unique_ptr被销毁时,资源会自动回收。因为unique_ptr任何资源只能有一个,所以任何复制a的尝试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使用引用计数来跟踪有多少指针引用资源,因此您需要注意不要引入任何引用周期。


简而言之:


使用unique_ptr时您需要一个指针时单指针被销毁,将被回收的对象。

shared_ptr当您想要多个指向同一资源的指针时使用。

希望这可以帮助!


查看完整回答
反对 回复 2019-08-23
?
森林海

TA贡献2011条经验 获得超2个赞

在指针中包装指针时,unique_ptr不能有多个副本unique_ptr。的shared_ptr保持参考计数器,它计数所存储的指针的副本的数目。每次shared_ptr复制a时,此计数器都会递增。每次a shared_ptr被破坏时,该计数器递减。当此计数器达到0时,存储的对象将被销毁。


查看完整回答
反对 回复 2019-08-23
?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

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在你真正需要共同责任时才使用。


查看完整回答
反对 回复 2019-08-23
  • 3 回答
  • 0 关注
  • 1745 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信