Boost logo

Boost Users :

From: Alan M. Carroll (amc_at_[hidden])
Date: 2008-07-30 17:39:19


Here's the class we use in production:

/** Helper template mixin for @c boost::intrusive_ptr.
    To add support for intrusive pointer to class @c T, it should inherit from
    @c reference_counter<T>. This will

    - provide a reference count member
    - force the reference count to initialize to zero
    - define the add and release global functions required by @c intrusive_ptr

    If this class is not inherited publically, then the class @c T must declare
    the global functions as friends to permit them to cast @c T* to @c reference_counter<T>*.
    This can be done with the following two lines, with either the @c self typedef
    or the string "self" replaced by the actual name of class @c T.

    @code
    friend void boost::intrusive_ptr_add_ref(self*);
    friend void boost::intrusive_ptr_release(self*);
    @endcode

    @note Due to changes in the C++ standard and design decisions in gcc,
    it is no longer possible to declare a template parameter as a friend class.
    (Basically, you can't use a typedef in a friend declaration and gcc treats
    template parameters as typedefs).

    @note You can use this with insulated (by name only) classes. The important
    thing is to make sure that any class that uses an @c intrusive_ptr to a
    by name only class has all of its constructors and destructors declared
    in the header and defined in the implementation translation unit. If the
    compiler generates any of those, it will not compile due to missing
    functions or methods.

 */

template <typename T> class reference_counter
{
protected:
    typedef reference_counter self; //!< Useful for self type reference

    //! Default constructor.
    reference_counter() : m_reference_count(0) { }

    /** Copy constructor.
            @note Always initialize to zero. Ignore the source count.
            This makes it nicer for clients who can now use the default
            copy constructor.
        */
    reference_counter(self const&) : m_reference_count(0) { }

    /** Assignment operator.
            @note Prevent the count from being assigned.
        */
    self& operator= (self const&) { return *this; }

    int m_reference_count; //!< The reference count

    //! Define the helper functions and give them access
    //!@{
    friend inline void intrusive_ptr_add_ref(T* t) { ++(static_cast<self*>(t)->m_reference_count); }
    friend inline void intrusive_ptr_release(T* t) { if (--(static_cast<self*>(t)->m_reference_count) <= 0) delete t; }
    //!@}
};


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net