intrusive_ptr in c++11
Does c++11 have something equivalent to boost::intrusive_ptr?
No.
It does have std::make_shared
which means std::shared_ptr
is almost (see note below) as efficient as an intrusive smart pointer, because the reference counts will be stored adjacent in memory to the object itself, improving locality of reference and cache usage. It also provides std::enable_shared_from_this
which allows you to retrieve a std::shared_ptr
when you only have a built-in pointer to an object owned by a shared_ptr
, but that doesn't allow you to manage the object using different smart pointer types.
shared_ptr
expects to be entirely responsible for managing the object. A different smart pointer type might only manage the "strong" refcount and not the "weak" refcount, which would allow the counts to get out of sync and break the invariants of shared_ptr
.
Note: Using make_shared
allows shared_ptr
to be almost as efficient as an intrusive pointer. The object and the reference counting info can be allocated in a single chunk of memory when make_shared
is used, but there will still be two reference counts (for the "strong" and "weak" counts) which isn't the case for intrusive pointers as they don't support a weak_ptr
. Also, the shared_ptr
object itself always has to store two pointers (the one that will be returned by shared_ptr::get()
and another pointer to the "control block" that contains the reference counts and knows the dynamic type of the owned object) so has a larger footprint than an intrusive pointer.
Aarkan
Updated on October 12, 2020Comments
-
Aarkan over 3 years
Does C++11 have something equivalent to
boost::intrusive_ptr
?My problem is that I have a C-style interface over my C++ code. Both sides of the interface can use C++, but exposing the C interface is required for compatibility reasons. I cannot use
std::shared_ptr
because I have to manage the object through two (or more) smart pointers. I am unable to figure out a solution with something likeboost::intrusive_ptr
. -
ComicSansMS almost 10 yearsintrusive pointers that don't support a weak_ptr - To clarify: Intrusive pointers cannot support (thread-safe) weak_ptr by design. The refcount needs to be stored outside the object, otherwise any lock attempt on a weak pointer would race with the destruction of the object. In other words: Each weak pointer has shared ownership on the refcount. So if the refcounter is inseparable from the object itself (as is the case with an intrusive pointer), the weak pointer hence also has (strong) shared ownership on the object itself, which contradicts the concept of a weak pointer.
-
Jonathan Wakely almost 10 years@ComicSansMS, indeed - that was poor wording on my part. I've reworded the note slightly and I hope it's clearer. Thanks.
-
pqnet over 9 years@ComicSansMS it is not just a problem with threads: weak pointers cannot check if the object is still alive because if it has been destructed already they would read
free
d memory -
ICTMitchell over 9 yearsYou could also store references to all weak pointers and clear them on destruction, i.e. the behavious Qt's QPointer (although impl might be different).
-
Yakov Galka almost 9 years
shared_ptr
violates the "you don't pay for the what you don't use" principle. It stores at least two counters plus a deleter (at least four words in total?), plus the size of everyshared_ptr
is two words instead of one. This is quite a lot to pay for linked structures with small nodes where weak references aren't needed. (Think of a rope implementation) -
Lothar over 6 yearsIt's much more space efficient because a shared pointer is 2 pointer and an intrusive_ptr is just one.
-
Caleth over 5 years@ybungalobill "you don't pay for the what you don't use" doesn't apply for picking the wrong tool for the job. If you don't need shared ownership, don't use
shared_ptr
. -
user686249 over 2 years@Caleth Most often I seem to need shared ownership without a custom deleter and without the need for weak pointer support. Which (standard) tool other than
shared_ptr
should I use? -
Caleth over 2 years@user686249 do you need shared ownership, or would one owner and many non-owning pointers suffice? The latter is far more common ime. The owner can be a container, or automatic duration storage, it need not be
std::unique_ptr
-
user686249 over 2 years@Caleth Yes, of course, exclusive ownership is by far the most common, but when I need shared ownership, I often don't need a custom deleter and virtually never
weak_ptr
support. I still pay for both features, however, when usingshared_ptr
. I'm referring to your suggestion, thatshared_ptr
might be the wrong tool for the job. I'm just unaware of any (standard) alternative. -
Jonathan Wakely over 2 years@user686249 The weak count does take up space even if you don't need it, but how do you pay for a custom deleter if you don't use it? That should be zero-overhead. To answer the question, there is no other shared ownership pointer in the standard library; it doesn't provide every possible solution for every problem.