unique_ptr和shared_ptr之间的区别

发布于 2024-11-27 04:00:21 字数 338 浏览 1 评论 0原文

可能的重复:
pimpl:shared_ptr 或 unique_ptr
智能指针(boost)解释

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

Possible Duplicates:
pimpl: shared_ptr or unique_ptr
smart pointers (boost) explained

Could someone explain differences between shared_ptr and unique_ptr?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

£烟消云散 2024-12-04 04:00:21

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

使用 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 使用引用计数 跟踪有多少指针引用某个资源,因此需要小心不要引入任何引用循环。

简而言之:

  1. 当您想要指向一个对象的单个指针(该对象在该单个指针被销毁时将被回收)时,请使用unique_ptr
  2. 当您想要多个指针指向同一资源时,请使用shared_ptr

Both of these classes are smart pointers, which means that they automatically (in most cases) will deallocate the object that they point at when that object can no longer be referenced. The difference between the two is how many different pointers of each type can refer to a resource.

When using unique_ptr, there can be at most one unique_ptr pointing at any one resource. When that unique_ptr is destroyed, the resource is automatically reclaimed. Because there can only be one unique_ptr to any resource, any attempt to make a copy of a unique_ptr will cause a compile-time error. For example, this code is illegal:

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

However, unique_ptr can be moved using the new move semantics:

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

Similarly, you can do something like this:

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

    /* ... */

    return myPtr;
}

This idiom means "I'm returning a managed resource to you. If you don't explicitly capture the return value, then the resource will be cleaned up. If you do, then you now have exclusive ownership of that resource." In this way, you can think of unique_ptr as a safer, better replacement for auto_ptr.

shared_ptr, on the other hand, allows for multiple pointers to point at a given resource. When the very last shared_ptr to a resource is destroyed, the resource will be deallocated. For example, this code is perfectly legal:

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

Internally, shared_ptr uses reference counting to track how many pointers refer to a resource, so you need to be careful not to introduce any reference cycles.

In short:

  1. Use unique_ptr when you want a single pointer to an object that will be reclaimed when that single pointer is destroyed.
  2. Use shared_ptr when you want multiple pointers to the same resource.
淡写薰衣草的香 2024-12-04 04:00:21

如果您在某处有一个动态对象,而一个消费者对此负有唯一(因此“唯一”)责任,则 unique_ptr 是首选的轻量级智能指针 - 可能是一个包装器需要维护一些动态分配的对象的类。 unique_ptr 的开销非常小。它不可复制,但可移动。它的类型templateclass unique_ptr;,因此它依赖于两个模板参数。

unique_ptr 也是 auto_ptr 想要在旧 C++ 中实现的功能,但由于该语言的限制而无法实现。

另一方面,shared_ptr 是一种非常不同的动物。明显的区别是,您可以让许多使用者分担动态对象的责任(因此“共享”),并且只有当所有共享指针消失时,该对象才会被销毁。此外,您还可以观察弱指针,如果它们所跟随的共享指针消失了,它们就会被智能地通知。

在内部,shared_ptr 还有更多功能:有一个引用计数,它会自动更新以允许在并发代码中使用。此外,还有大量的分配正在进行,一个用于内部簿记“引用控制块”,另一个(通常)用于实际的成员对象。

但还有另一个很大的区别:共享指针类型是 always templateclass shared_ptr;,尽管您可以使用自定义删除器使用自定义分配器来初始化它。删除器和分配器使用类型擦除和虚函数分派进行跟踪,这增加了类的内部重量,但具有巨大的优势,即类型 T 的不同类型的共享指针都是兼容的,没有重要的是删除和分配细节。从而真实地表达了“T的共同责任”的理念,而不给消费者带来细节上的负担!

shared_ptrunique_ptr 都被设计为按值传递(对唯一指针具有明显的可移动性要求)。两者都不应该让您担心开销,因为它们的功能确实令人震惊,但如果您有选择,更喜欢 unique_ptr,并且仅在您确实需要分担责任时才使用 shared_ptr

unique_ptr is the light-weight smart pointer of choice if you just have a dynamic object somewhere for which one consumer has sole (hence "unique") responsibility -- maybe a wrapper class that needs to maintain some dynamically allocated object. unique_ptr has very little overhead. It is not copyable, but movable. Its type is template <typename D, typename Deleter> class unique_ptr;, so it depends on two template parameters.

unique_ptr is also what auto_ptr wanted to be in the old C++ but couldn't because of that language's limitations.

shared_ptr on the other hand is a very different animal. The obvious difference is that you can have many consumers sharing responsibility for a dynamic object (hence "shared"), and the object will only be destroyed when all shared pointers have gone away. Additionally you can have observing weak pointers which will intelligently be informed if the shared pointer they're following has disappeared.

Internally, shared_ptr has a lot more going on: There is a reference count, which is updated atomically to allow the use in concurrent code. Also, there's plenty of allocation going on, one for an internal bookkeeping "reference control block", and another (often) for the actual member object.

But there's another big difference: The shared pointers type is always template <typename T> class shared_ptr;, and this is despite the fact that you can initialize it with custom deleters and with custom allocators. The deleter and allocator are tracked using type erasure and virtual function dispatch, which adds to the internal weight of the class, but has the enormous advantage that different sorts of shared pointers of type T are all compatible, no matter the deletion and allocation details. Thus they truly express the concept of "shared responsibility for T" without burdening the consumer with the details!

Both shared_ptr and unique_ptr are designed to be passed by value (with the obvious movability requirement for the unique pointer). Neither should make you worried about the overhead, since their power is truly astounding, but if you have a choice, prefer unique_ptr, and only use shared_ptr if you really need shared responsibility.

╭⌒浅淡时光〆 2024-12-04 04:00:21

unique_ptr
是一个独占对象的智能指针。

shared_ptr
是共享所有权的智能指针。它既是可复制又是可移动。多个智能指针实例可以拥有相同的资源。一旦拥有该资源的最后一个智能指针超出范围,该资源就会被释放。

unique_ptr
is a smart pointer which owns an object exclusively.

shared_ptr
is a smart pointer for shared ownership. It is both copyable and movable. Multiple smart pointer instances can own the same resource. As soon as the last smart pointer owning the resource goes out of scope, the resource will be freed.

晨与橙与城 2024-12-04 04:00:21

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

When wrapping a pointer in a unique_ptr you cannot have multiple copies of unique_ptr. The shared_ptr holds a reference counter which count the number of copies of the stored pointer. Each time a shared_ptr is copied, this counter is incremented. Each time a shared_ptr is destructed, this counter is decremented. When this counter reaches 0, then the stored object is destroyed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文