I've been making some objects using the pimpl idiom, but I'm not sure whether to use std::shared_ptr
or std::unique_ptr
.
I understand that std::unique_ptr
is more efficient, but this isn't so much of an issue for me, as these objects are relatively heavyweight anyway so the cost of std::shared_ptr
over std::unique_ptr
is relatively minor.
I'm currently going with std::shared_ptr
just because of the extra flexibility. For example, using a std::shared_ptr
allows me to store these objects in a hashmap for quick access while still being able to return copies of these objects to callers (as I believe any iterators or references may quickly become invalid).
However, these objects in a way really aren't being copied, as changes affect all copies, so I was wondering that perhaps using std::shared_ptr
and allowing copies is some sort of anti-pattern or bad thing.
Is this correct?
An object referenced by the contained raw pointer will not be destroyed until reference count is greater than zero i.e. until all copies of shared_ptr have been deleted. So, we should use shared_ptr when we want to assign one raw pointer to multiple owners. // referring to the same managed object.
When you copy a std::shared_ptr in a thread, all is fine. At first to (2). By using copy construction for the std::shared_ptr localPtr, only the control block is used. That is thread-safe.
shared_ptr are noticeably slower than raw pointers. That's why they should only be used if you actually need shared ownership semantics. Otherwise, there are several other smart pointer types available. scoped_ptr and auto_ptr (C++03) or unique_ptr (C++0x) both have their uses.
No, swap isn't thread safe, but there's another function that is: atomic_store(&global, sp); There's also atomic_exchange which returns the old value, if you need that.
I've been making some objects using the pimpl idiom, but I'm not sure whether to used
shared_ptr
orunique_ptr
.
Definitely unique_ptr
or scoped_ptr
.
Pimpl
is not a pattern, but an idiom, which deals with compile-time dependency and binary compatibility. It should not affect the semantics of the objects, especially with regard to its copying behavior.
You may use whatever kind of smart pointer you want under the hood, but those 2 guarantee that you won't accidentally share the implementation between two distinct objects, as they require a conscious decision about the implementation of the copy constructor and assignment operator.
However, these objects in a way really aren't being copied, as changes affect all copies, so I was wondering that perhaps using
shared_ptr
and allowing copies is some sort of anti-pattern or bad thing.
It is not an anti-pattern, in fact, it is a pattern: Aliasing. You already use it, in C++, with bare pointers and references. shared_ptr
offer an extra measure of "safety" to avoid dead references, at the cost of extra complexity and new issues (beware of cycles which create memory leaks).
Unrelated to Pimpl
I understand
unique_ptr
is more efficient, but this isn't so much of an issue for me, as these objects are relatively heavyweight anyway so the cost ofshared_ptr
overunique_ptr
is relatively minor.
If you can factor out some state, you may want to take a look at the Flyweight pattern.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With