intrusive_ptr: proposal for common base class

Hi all, Sorry if this has been discussed yet, but I think there is an obvious pattern in the usage of intrusive_ptr which should be exposed as common functionality in boost. In most of the cases you just want to handle a simple reference count and delete the object which is held by the intrusive_ptr when the reference count is decreased to zero. It's very annoying that you currently have to write external add_ref/release functions for every class you want to use with this smart pointer. Additionaly, it makes the code unreadable. That's why I would like to suggest having a base class which provides the simplest functionality a user could expect from intrusive_ptr: handling the reference count and deleting the object. A class which should be maintained by intrusive_ptr can derive from it and would not have to provide any further interfaces. I'm not glad about the class name 'intrusive_ptr_base' but I don't have any good ideas at the moment :( Awaiting you comments! (code: see below) Stefan namespace boost { class intrusive_ptr_base; void intrusive_ptr_add_ref(intrusive_ptr_base*); void intrusive_ptr_release(intrusive_ptr_base*); class intrusive_ptr_base { friend void intrusive_ptr_add_ref(intrusive_ptr_base*); friend void intrusive_ptr_release(intrusive_ptr_base*); int ref_count__; protected: intrusive_ptr_base() : ref_count__(0) {} virtual ~intrusive_ptr_base() {} }; inline void intrusive_ptr_add_ref(intrusive_ptr_base* o) { ++o->ref_count__; } inline void intrusive_ptr_release(intrusive_ptr_base* o) { if (--o->ref_count__ == 0) { delete o; } } } // namespace

Stefan Slapeta wrote:
class intrusive_ptr_base { friend void intrusive_ptr_add_ref(intrusive_ptr_base*); friend void intrusive_ptr_release(intrusive_ptr_base*);
int ref_count__;
protected: intrusive_ptr_base() : ref_count__(0) {}
virtual ~intrusive_ptr_base() {}
I don't necessarily think this is a good idea, but I will only comment on the code. You can use CRTP here instead, to avoid the virtual destructor. Something like: template<class Derived> class intrusive_ptr_base { friend void intrusive_ptr_add_ref(intrusive_ptr_base* o) { ++o->ref_count__; } friend void intrusive_ptr_release(intrusive_ptr_base* o) { if (--o->ref_count__ == 0) { delete static_cast<Derived*>(o); } } int ref_count__; protected: intrusive_ptr_base() : ref_count__(0) {} }; -- Daniel Wallin

Daniel Wallin wrote:
I don't necessarily think this is a good idea,
Anyway, it's an idea :) It's just that it maybe could simplify 99% of the intrusive_ptr applications. I also played around with making the concept extendable (optionally forwarding the call again to 'external' intrusive_ptr_add_ref etc. after handling the reference count) but I couldn't imagine any situation where this would be useful.
You can use CRTP here instead, to avoid the virtual destructor.
Thanks! Stefan
participants (2)
-
Daniel Wallin
-
Stefan Slapeta