
Dear Boosters, The documentation of intrusive_ptr says "As a general rule, if it isn't obvious whether intrusive_ptr better fits your needs than shared_ptr, try a shared_ptr-based design first." but does not explain why. If the classes involved are all my own and deriving them all from a base class that implements reference-counting is not a problem, what are some reasons to prefer shared_ptr to intrusive_ptr? Thanks, Ilya

"As a general rule, if it isn't obvious whether intrusive_ptr better fits your needs than shared_ptr, try a shared_ptr-based design first."
but does not explain why.
If the classes involved are all my own and deriving them all from a base class that implements reference-counting is not a problem, what are some reasons to prefer shared_ptr to intrusive_ptr?
Because shared_ptr doesn't require *any* additional code (which should be designed, implemented, tested, supported, etc).

Igor R
Because shared_ptr doesn't require *any* additional code (which should be designed, implemented, tested, supported, etc).
Yes for a large I support that, but in some respects intrusive_ptr's have some benefit over shared_ptr's (e.g. you cannot pass a shared_ptr of urslef in ctor's etc.)

Igor R
OTOH, intrusive_ptr doesn't have a weak_ptr counterpart -- and this is much more problematic, imho.
Yes that's an important feature too, but the ctor case is also a common case (e.g. solvable by adding an extra static 'Create'). To my knowledge the following drawbacks exist for shared_ptr: - you cannot use enabled_shared_from_this in the constructor. - you cannot use shared_ptr's in the destructor. - (never make a new shared_ptr family to an already shared object). - (enabled_shared_from_this only usable if the object is created as shared_ptr, not on the stack or just on the heap). The shared_ptr in dtor sounds as a 'contradictio in terminis'. A common case is that you have a change manager in which you want to de-register yourself in a dtor. The changemanager has ofc weak_ptr's to the managed object.

OTOH, intrusive_ptr doesn't have a weak_ptr counterpart -- and this is much more problematic, imho.
Yes that's an important feature too, but the ctor case is also a common case (e.g. solvable by adding an extra static 'Create').
To my knowledge the following drawbacks exist for shared_ptr: - you cannot use enabled_shared_from_this in the constructor. - you cannot use shared_ptr's in the destructor. - (never make a new shared_ptr family to an already shared object). - (enabled_shared_from_this only usable if the object is created as shared_ptr, not on the stack or just on the heap).
Well, all these points either have a reasonable solution/workaround that doesn't complicate the design much, or describe a quite "marginal" use-case. But the lack of weak-ptr makes impossible an object existence tracking, which is commonly used in a wide range of tasks. In some cases this would complicate the design and make it more error-prone (eg. manual breaking of circular references), and in some other cases it renders completely impossible a use of some facilities (like Boost.Signals2).

Well, all these points either have a reasonable solution/workaround that doesn't complicate the design much, or describe a quite "marginal" use-case. But the lack of weak-ptr makes impossible an object existence tracking, which is commonly used in a wide range of tasks. In some cases this would complicate the design and make it more error-prone (eg. manual breaking of circular references), and in some other cases it renders completely impossible a use of some facilities (like Boost.Signals2).
Well I wouldnt say these items are 'marginal', because most come from real life scenarios. You can work around things but it is always that u have to remember that there were some boundary cases with shared_ptr. It took me some time to convince my colleagues to swap from raw pointers to shared pointers and having some boundary cases doesn't help then. I still prefer shared pointers, but I am not sure if all in all they would be better than e.g. intrusive_ptr's with ref counting (even without lacking the weak_ptr feature). Note that i look upon this from a client perspective (i.e. large data acquisition application), not from a library builder perspective.

On Fri, Jan 18, 2013 at 6:38 PM, ilya shlyakhter
Dear Boosters,
The documentation of intrusive_ptr says
"As a general rule, if it isn't obvious whether intrusive_ptr better fits your needs than shared_ptr, try a shared_ptr-based design first."
but does not explain why.
If the classes involved are all my own and deriving them all from a base class that implements reference-counting is not a problem, what are some reasons to prefer shared_ptr to intrusive_ptr?
Thanks,
Ilya _
Not sure if this has been mentioned, but an intrusive reference count can been seen as inherently ("philosophically") wrong - it is an external value, not an essential value of the class: class MyRefCount {... }; class Foo : MyRefCount { ... }; Foo foo; does it make sense to ask what the ref count on a static or stack allocated Foo is? Taking intrusive_ptr or a shared_ptr on a non-allocated object is wrong in either case, but only intrusive_ptr makes it part of the class. A non-shared Foo has an unused reference count - maybe not a big deal in term of efficiency, but only philosophically. Or do you hide the constructor and make a factory function - so you can never have a Foo outside of an intrusive_ptr? Having said all that, I actually often prefer intrusive_ptr: - easy binary interface (ie exposing objects from DLLs) as the intrusive_ptr_add_ref(Foo) is easily exported. - easier to use than enable_shared_from_this.

Gottlob Frege wrote:
On Fri, Jan 18, 2013 at 6:38 PM, ilya shlyakhter
wrote: Dear Boosters,
The documentation of intrusive_ptr says
"As a general rule, if it isn't obvious whether intrusive_ptr better fits your needs than shared_ptr, try a shared_ptr-based design first."
but does not explain why.
If the classes involved are all my own and deriving them all from a base class that implements reference-counting is not a problem, what are some reasons to prefer shared_ptr to intrusive_ptr?
Thanks,
Ilya _
Not sure if this has been mentioned, but an intrusive reference count can been seen as inherently ("philosophically") wrong - it is an external value, not an essential value of the class:
class MyRefCount {... };
class Foo : MyRefCount { ... };
Foo foo;
does it make sense to ask what the ref count on a static or stack allocated Foo is? Taking intrusive_ptr or a shared_ptr on a non-allocated object is wrong in either case, but only intrusive_ptr makes it part of the class.
To me, it does not make sense for Foo to have an intrusive pointer if it is intended to be created on the stack or statically. So I would use intrusive pointer only if objects were to be created on the heap (otherwise I'd use a linked (non-intrusive) pointer). And I agree the intrusive count should not be public. Louis.
participants (5)
-
gast128
-
Gottlob Frege
-
Igor R
-
ilya shlyakhter
-
Louis Lavery