unique_ptr和shared_ptr之间的区别
有人可以解释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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这两个类都是智能指针,这意味着当无法再引用它们所指向的对象时,它们会自动(在大多数情况下)释放该对象。两者之间的区别在于每种类型有多少个不同的指针可以引用资源。
使用
unique_ptr
时,最多可以有一个unique_ptr
指向任一资源。当unique_ptr
被销毁时,资源将被自动回收。由于任何资源只能有一个unique_ptr
,因此任何复制unique_ptr
的尝试都会导致编译时错误。例如,此代码是非法的:但是,
unique_ptr
可以使用新的移动语义移动:类似地,您可以执行如下操作:
这个习语的意思是“我是如果您没有明确捕获返回值,那么该资源将被清理,那么您现在拥有该资源的独占所有权。”通过这种方式,您可以将
unique_ptr
视为auto_ptr
更安全、更好的替代品。另一方面,shared_ptr 允许多个指针指向给定的资源。当资源的最后一个
shared_ptr
被销毁时,该资源将被释放。例如,此代码是完全合法的:在内部,
shared_ptr
使用引用计数 跟踪有多少指针引用某个资源,因此需要小心不要引入任何引用循环。简而言之:
unique_ptr
。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 oneunique_ptr
pointing at any one resource. When thatunique_ptr
is destroyed, the resource is automatically reclaimed. Because there can only be oneunique_ptr
to any resource, any attempt to make a copy of aunique_ptr
will cause a compile-time error. For example, this code is illegal:However,
unique_ptr
can be moved using the new move semantics:Similarly, you can do something like this:
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 forauto_ptr
.shared_ptr
, on the other hand, allows for multiple pointers to point at a given resource. When the very lastshared_ptr
to a resource is destroyed, the resource will be deallocated. For example, this code is perfectly legal: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:
unique_ptr
when you want a single pointer to an object that will be reclaimed when that single pointer is destroyed.shared_ptr
when you want multiple pointers to the same resource.如果您在某处有一个动态对象,而一个消费者对此负有唯一(因此“唯一”)责任,则
unique_ptr
是首选的轻量级智能指针 - 可能是一个包装器需要维护一些动态分配的对象的类。unique_ptr
的开销非常小。它不可复制,但可移动。它的类型是templateclass unique_ptr;
,因此它依赖于两个模板参数。unique_ptr
也是auto_ptr
想要在旧 C++ 中实现的功能,但由于该语言的限制而无法实现。另一方面,
shared_ptr
是一种非常不同的动物。明显的区别是,您可以让许多使用者分担动态对象的责任(因此“共享”),并且只有当所有共享指针消失时,该对象才会被销毁。此外,您还可以观察弱指针,如果它们所跟随的共享指针消失了,它们就会被智能地通知。在内部,
shared_ptr
还有更多功能:有一个引用计数,它会自动更新以允许在并发代码中使用。此外,还有大量的分配正在进行,一个用于内部簿记“引用控制块”,另一个(通常)用于实际的成员对象。但还有另一个很大的区别:共享指针类型是 always
templateclass shared_ptr;
,尽管您可以使用自定义删除器和使用自定义分配器来初始化它。删除器和分配器使用类型擦除和虚函数分派进行跟踪,这增加了类的内部重量,但具有巨大的优势,即类型T
的不同类型的共享指针都是兼容的,没有重要的是删除和分配细节。从而真实地表达了“T
的共同责任”的理念,而不给消费者带来细节上的负担!shared_ptr
和unique_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 istemplate <typename D, typename Deleter> class unique_ptr;
, so it depends on two template parameters.unique_ptr
is also whatauto_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 typeT
are all compatible, no matter the deletion and allocation details. Thus they truly express the concept of "shared responsibility forT
" without burdening the consumer with the details!Both
shared_ptr
andunique_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, preferunique_ptr
, and only useshared_ptr
if you really need shared responsibility.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
andmovable
. 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.将指针包装在
unique_ptr
中时,不能拥有unique_ptr
的多个副本。shared_ptr
拥有一个引用计数器,用于计算所存储指针的副本数量。每次复制shared_ptr
时,该计数器都会递增。每次shared_ptr
被破坏时,该计数器都会递减。当该计数器达到 0 时,存储的对象将被销毁。When wrapping a pointer in a
unique_ptr
you cannot have multiple copies ofunique_ptr
. Theshared_ptr
holds a reference counter which count the number of copies of the stored pointer. Each time ashared_ptr
is copied, this counter is incremented. Each time ashared_ptr
is destructed, this counter is decremented. When this counter reaches 0, then the stored object is destroyed.