//============================================================================ // Contents: // // Definition of countability abstract base class that confers reference // counting features for derived classes. Global functions are provided that // make any class derived from countability satisfy the countability // requirements defined for any parameter of countable_ptr. // // The code is in many ways a traditional implementation of the Counted Body // idiom in that it is intrusive, ie countability is acquired explicitly and // statically by derivation for a given class. This means that the reference // count is explicitly a part of objects even if it is unused (eg in the case // of composite members or auto variables), and that only classes over which // you have control can use it. However, by satisfying the countability // requirements for countable_ptr no new smart pointer class is required to // use classes derived from countability. // // History: // // Initial version created by Kevlin Henney, kevlin@acm.org, January 1998. // // Permissions: // // Copyright Kevlin Henney, 1998. All rights reserved. // // Permission to use, copy, modify, and distribute this software for any // purpose is hereby granted without fee, provided that this copyright and // permissions notice appear in all copies and derivatives, and that no // charge may be made for the software and its documentation except to cover // cost of distribution. // // This software is provided "as is" without express or implied warranty. // // Notes: // // Although the countable requirements specified in "countable_ptr.hpp" are // satisfied by countability and its derived classes, there is no source // dependency on that header; countability may be used, if so desired, // independently of countable_ptr. // // For practical reasons the global, rather than a named namespace, has been // used to hold the contents of this header. In future the use of a separate // namespace is preferred and recommended. // // This code has been written to conform to standard C++ (in final draft // status at the time of writing). It has been compiled successfully using // the operational subset of standard features implemented by Microsoft // Visual C++ 5.0. //============================================================================ #ifndef COUNTABILITY_INCLUDED #define COUNTABILITY_INCLUDED #include // for size_t //---------------------------------------------------------------------------- // Description: // // Definition of countability abstract base class, which provides a mechanism // for reference counting for use by derived classes. // // Notes: // // The countability class is intended to be used as a mix-in, but without // any polymorphic behaviour; its principle aim is to provide implementation // for derived classes (ie a mix-imp). As such, there are no virtual // functions. Making the constructor protected has the effect of making the // class abstract, and making the destructor ensures that unsafe destruction // via a counability * is not possible. // // Copying is not considered meaningful for such a class, and so copying // semantics have been disabled. This does mean that derived classes are // required to define their own copying semantics if that is what is // required, but this is expected of any good citizen class and so is not // considered an unreasnable imposition. // // Countability is not seen as a concrete property of derived classes, and // therefore is not part of an object's logical state. This means that all // the operations in countability are const, and the count member is mutable. // If your compiler does not support mutable you can remove it and modify the // implementation to use const_cast where appropriate. // // Related member functions (method categories) are placed under their own // commented access specifiers. //---------------------------------------------------------------------------- class countability { public: // manipulation void acquire() const; void release() const; size_t acquired() const; protected: // construction and destruction countability(); ~countability(); private: // representation mutable size_t count; private: // prevention countability(const countability &); countability &operator=(const countability &); }; //---------------------------------------------------------------------------- // Description: // // Declaration of global functions that allow classes derived from // countability to satisfy countable requirements. // // Requirements: // // The type used for the template parameter for the dispose function must be // derived from countability. // // Notes: // // If your compiler supports older style template functions that require an // exact match on the type of non-templated arguments, the dispose function // will cause problems and your code will not compile. This problem can be // worked around in part by making the type of the second argument the same // as the first. However, this means that as dispose cannot be overloaded // successfully, only one countable strategy can be used per translation // unit. //---------------------------------------------------------------------------- void acquire(const countability *); void release(const countability *); size_t acquired(const countability *); template void dispose(const countability_derived *, const countability *); //---------------------------------------------------------------------------- // Description: // // Definition of dispose template function. // // Notes: // // This definition could be placed in a separate header file or, for systems // that support separate compilation of templates, in a source file. // // The function is a likely candidate for explicit inlining, but for the // purposes of demonstration such an optimisation has not been deemed // necessary. //---------------------------------------------------------------------------- template void dispose(const countability_derived *ptr, const countability *) { delete ptr; } #endif