Possible Duplicates:
pimpl: shared_ptr or unique_ptr
smart pointers (boost) explained
Could someone explain differences between shared_ptr and unique_ptr?
Possible Duplicates:
pimpl: shared_ptr or unique_ptr
smart pointers (boost) explained
Could someone explain differences between shared_ptr and unique_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:
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
can be a little buggy regarding deleters. shared_ptr
will always do "the right thing", as long it was created with make_shared
. But if you create a unique_ptr<Derived>
, then convert it to unique_ptr<Base>
, and if Derived is virtual and Base is not, then the pointer will be deleted through the wrong type and there can be undefined behaviour. This can be fixed with an appropriate deleter-type in the unique_ptr<T, DeleterType>
, but the default is to use the riskier version because it is a little more efficient. –
Chazan unique_ptr
will behave like a raw pointer that you can't forget to delete
: if you forget to make the dtor virtual, it's on you. –
Comment make_unique
instead of new
. It is cleaner, safer and more efficient. –
Cockade MyFunction()
into another pointer in the caller's scope? –
Apostasy 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.
std::move(x)
as an argument, which means that x
is then moved-from. –
Mcatee unique_ptr
for all objects, you'd basically end up with Rust with uglier syntax. Borrowing could be implemented by moving unique_ptr
in as function arguments and then moving the unique_ptr
back during function return. If you also had threading implementation following the same rules you could have thread safety similar way as Rust has (that is, data races are not possible because safe Rust cannot race to shared data). –
Dieldrin 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.
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.
shared_ptr
that are copies of each other is able to determine when the last member of the family is destructed. –
Comment © 2022 - 2024 — McMap. All rights reserved.