The boost::intrusive_ptr template is useful to handle objects with a reference count, but it does not offer any helper functions to create the reference counted objects.
The intrusive_ptr_object helpers try to offer such support.
To create an object which is reference counted:
#include <intrusive_ptr_object.hpp> class MyBaseClass : public virtual boost::intrusive_ptr_base { ... };
// You have specialized constructors #include <intrusive_ptr_object.hpp> class MyClass_heap : public MyClass, public boost::intrusive_ptr_object { ... }; // You have one constructor with no parameters (and default copy) #include <intrusive_ptr_object.hpp> typedef boost::intrusive_ptr_heap<MyClass> MyClass_heap;
void f() { MyClass my_object; ... // Try to use the pointer in an intrusive_ptr<> template makes your program crash boost::intrusive_ptr<MyClass> ptr(&my_object); }
class OtherObject { // a bar pointer as defined in my old library! Set(MyClass *ptr) { m_ptr = ptr; } boost::intrusive_ptr<MyClass> m_ptr; }; void f(OtherObject *oo) { boost::intrusive_ptr<MyClass> ptr(new MyClass); ... oo->Set(ptr); ... // the object in ptr is not deleted when we exit since // the object oo has a reference to it. }
You can create two different types of objects: a stack or composition object (as usual) or a heap object. A heap object can be referenced, the others cannot and you get an error at runtime.
You can pass a bare pointer of MyClass to other objects and they still can keep a reference by dynamically casting to the intrusive_ptr_object part of the object.
namespace boost { class intrusive_ptr_object { public: intrusive_ptr_object() throw(); virtual ~intrusive_ptr_object() = 0; void add_ref(); void release(); }; class intrusive_ptr_base { public: virtual ~intrusive_ptr_base() = 0; }; inline void intrusive_ptr_add_ref(intrusive_ptr_base *a); inline void intrusive_ptr_release(intrusive_ptr_base *a); template<class T> class intrusive_ptr_heap; }
intrusive_ptr_object();Postconditions: reference is zero (0)
Throws: nothing
~intrusive_ptr_object();Preconditions: reference must be zero (0)
Throws: assertion if reference is not zero
add_ref();Postconditions: reference is one more
Throws: nothing
Thread: this function is thread safe
release();Effects: reference is one less
Postconditions: if the reference reached zero (0), the object is deleted
Throws: an assertion if the reference count is zero (0) on entry
Thread: this function is thread safe
~intrusive_ptr_base();Effects: none
Throws: an assertion if the reference count is zero (0) on entry
void intrusive_ptr_add_ref(intrusive_ptr_base *a); void intrusive_ptr_release(intrusive_ptr_base *a);Effects: calls the corresponding function of the intrusive_ptr_object
Note: these functions are implementation details but they still need to be defined publicly for the intrusive_ptr implementation to be capable to find them.
template<class T> class intrusive_ptr_heap;Usage: create typedef's of a new classes derived from T and intrusive_ptr_object.
Note: this template will fail if class T has constructors with parameters.
Copyright (c) Alexis Wilke and Doug Barbieri
Permission to copy, use, modify, sell and distribute this document is granted provided
this copyright notice appears in all copies. This document is provided "as is" without
express or implied warranty, and with no claim as to its suitability for any purpose.