tags:

views:

213

answers:

2

intrusive_ptr requires intrusive_ptr_add_ref and intrusive_ptr_release to be defined. Why isn't a base class provided which will do this? There is an example here: http://lists.boost.org/Archives/boost/2004/06/66957.php, but the poster says "I don't necessarily think this is a good idea". Why not?

Update: I don't think the fact that this class could be misused with Multiple Inheritance is reason enough. Any class which derives from multiple base classes with their own reference count would have the same issue. Whether these refcounts are implemented via a base class or not makes no difference.

I don't think there's any issue with multithreading; shared_ptr offers atomic reference counting and this class could too.

+4  A: 

The problem would be with Multiple Inheritance. If you inherit from 2 objects implementing this base, then you have 2 counters for your single object... and that could cause havoc.

Thus you would need to make the ptr_add and ptr_release methods virtual, so that the derived class may implement an override to properly synchronize the multiple counters at once... Some performance penalty here, especially since most of the times it would be completely unnecessary (there would be no override) because it's only useful for Multiple Inheritance after all.

And of course in Multi-Threaded environments you could have (for short periods of time) desynchronized counters (the first was incremented but the thread was interrupted before the second was) I can't think yet of any problem it may cause, but it's not a sane situation.

You also add clutter to the class, some clients may not need reference counting after all (if they create the object on the stack).

I think it's not a good idea ;)

Matthieu M.
Multiple inheritance: This problem also occurs when you have two base classes which implement their own reference count. Whether this refcount is implemented via a base class or not makes no difference.Multi-Threaded: shared_ptr has atomic increment/decrement, so this class could too. "some clients may not need reference counting": that's a reason why you wouldn't use intrusive_ptr, not why there isn't a base class.
Jon
@Jon: I agree on the Multiple Inheritance, indeed you can implement intrusive reference counting without a base class. However I disagree on the 2 other remarks: for MT `shared_ptr` provides atomic semantics easily because it only has one counter, if you have several counters to maintain in a coherent state, then you need explicit locking (no more atomic ops available) and this means consequent overhead... follow the white rabbit...
Matthieu M.
For the `intrusive_ptr` part: I am partial here, but I always thought that the intrusive approach was "wrong" in the sense it bundled together both a "functional" class and a "management" behavior. So this is effectively a criticism on the intrusive reference counting mechanism. I find the `shared_ptr` approach more solid here, and the fact that you can't accidentally have two counters for a single set of `shared_ptr` is a nice bonus.
Matthieu M.
@Matthieu: this class would be derived from at a leaf class to ensure there was only one counter. It's the same as the MI argument: one can incorrectly put refcounts in base classes and end up with several of them, but this is independent of whether the refcounts were implemented using this proposed base class or not. Agree that shared_ptr is usually preferable, but intrusive_ptr has some benefits so it's a trade-off.
Jon
+1  A: 

It's so you can use intrusive_ptr with classes that already implement add and release.

Chris Card
There are other reasons to use intrusive_ptr (memory footprint, performance, constructing from arbitrary raw pointer)
Jon