home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cset21v1.zip / IBMCPP / IBMCLASS / IREFCNT.HPP < prev    next >
C/C++ Source or Header  |  1993-10-22  |  12KB  |  235 lines

  1. #ifndef _IREFCNT_
  2. #define _IREFCNT_
  3. /*******************************************************************************
  4. * FILE NAME: irefcnt.hpp                                                       *
  5. *                                                                              *
  6. * DESCRIPTION:                                                                 *
  7. *   Declaration of the class(es):                                              *
  8. *     IRefCounted - Class providing generic "reference coutned" semantics      *
  9. *     IReference  - Template class serving as reference to IRefCounted objects *
  10. *                                                                              *
  11. * COPYRIGHT:                                                                   *
  12. *   Licensed Materials - Property of IBM                                       *
  13. *   (C) Copyright IBM Corporation 1992, 1993                                   *
  14. *   All Rights Reserved                                                        *
  15. *   US Government Users Restricted Rights - Use, duplication, or disclosure    *
  16. *   restricted by GSA ADP Schedule Contract with IBM Corp.                     *
  17. *                                                                              *
  18. *******************************************************************************/
  19. #ifndef _IVBASE_
  20.   #include <ivbase.hpp>
  21. #endif
  22.  
  23. #ifndef _IEXCEPT_
  24.   #include <iexcept.hpp>
  25. #endif
  26.  
  27. #ifndef _ICCONST_
  28.   #include <icconst.h>
  29. #endif
  30.  
  31. /*----------------------------------------------------------------------------*/
  32. /* Align classes on four byte boundary.                                       */
  33. /*----------------------------------------------------------------------------*/
  34. #pragma pack(4)
  35.  
  36. class IRefCounted : public IVBase {
  37. typedef IVBase
  38.   Inherited;
  39. /*******************************************************************************
  40. * The IRefCounted class is a public base class for any class that will be      *
  41. * reference counted.  Such inheritance conveys the functional characteristics  *
  42. * of maintaining a count of all references to the object and deferring         *
  43. * destruction until all such references are destroyed.                         *
  44. *                                                                              *
  45. * Objects of this class, by necessity, can only be allocated in free store.    *
  46. * This is enforced by making the destructor for this class protected.  As a    *
  47. * result, only IRefCounted::removeRef and subclass destructors are permitted   *
  48. * to call IRefCounted::IRefCounted.  Subclasses should make their destructors  *
  49. * protected, also.                                                             *
  50. *                                                                              *
  51. * Typically, use of this class is paired with the corresponding use of         *
  52. * IReference<T> (where T is the subclass of IRefCounted).                      *
  53. *******************************************************************************/
  54. public:
  55. /*--------------------------- Reference Counting -------------------------------
  56. | Use these functions to manage the object's reference count:                  |
  57. |   addRef    - Increments the reference count, such as when a new reference   |
  58. |               is established.                                                |
  59. |   removeRef - Decrements the reference count and deletes the object if it    |
  60. |               goes to 0.                                                     |
  61. |   useCount  - Returns the use count for the object.                          |
  62. ------------------------------------------------------------------------------*/
  63. virtual void
  64.   addRef    ( ),
  65.   removeRef ( );
  66.  
  67. unsigned
  68.   useCount ( ) const
  69.     {
  70.     return this->refCount;
  71.     }
  72.  
  73. protected:
  74. /*------------------------- Constructor and Destructor -------------------------
  75. | The constructor initializes the use count to 1.  This presumes that the      |
  76. | newly constructed object's address is immediately used by some reference     |
  77. | (or functionally equivalent) object.  The object that created the            |
  78. | IRefCounted object should not call addRef because it is already marked as    |
  79. | referenced by the constructor itself.                                        |
  80. |                                                                              |
  81. | The destructor is protected to disable creation of non-free store objects.   |
  82. ------------------------------------------------------------------------------*/
  83.   IRefCounted ( );
  84.  
  85.   ~IRefCounted ( );
  86.  
  87. private:
  88. /*--------------------------------- Private -----------------------------------*/
  89. unsigned
  90.   refCount;
  91. }; // class IRefCounted
  92.  
  93. template < class T >
  94. class IReference : public IBase {
  95. /*******************************************************************************
  96. * The template class IReference is derived from classes that wish to serve as  *
  97. * references.  Instances of such classes will serve as smart pointers to       *
  98. * instances of the referenced class.  Creating instances of this class will    *
  99. * increment the use count of the referenced object.  Destruction of the        *
  100. * object will cause the use count of the referenced object to be decremented.  *
  101. *                                                                              *
  102. * Typically, this class will only be referenced explicitly as a public base    *
  103. * class of the class that provides the additional capability of the reference  *
  104. * class.  For example:                                                         *
  105. *                                                                              *
  106. *   class Foo { .. };                                                          *
  107. *   class FooRef : public IReference<Foo> {                                    *
  108. *   // Additional FooRef functions...                                          *
  109. *   };                                                                         *
  110. *                                                                              *
  111. * The reference counted class provided as the template argument should be      *
  112. * derived from the IRefCounted class.  It must have addRef and removeRef       *
  113. * member functions with equivalent semantics.                                  *
  114. *                                                                              *
  115. * To construct an IReference, you must provide a pointer to an instance of     *
  116. * the referenced (reference counted) class.  All constructors of the real      *
  117. * reference class (derived from IReference<T>) must provide such a pointer.    *
  118. * Otherwise, the reference class need take on no additional responsibilities.  *
  119. *                                                                              *
  120. * Notes:                                                                       *
  121. *   1. The semantics of such reference/referent classes perhaps have some      *
  122. *      subtle complexities.  Care must be taken in any case where either the   *
  123. *      reference or the referent behave in any sort of extraordinary fashion.  *
  124. *                                                                              *
  125. *   2. A class can also serve as a reference by having as a data member and    *
  126. *      instance of class IReference<T>.                                        *
  127. *                                                                              *
  128. *   3. All members of class IReference are public in order to permit the       *
  129. *      usage described in Note 2.                                              *
  130. *                                                                              *
  131. * Customization (Template Arguments)                                           *
  132. * Class IReference is a template class instantiated with the template          *
  133. * arguments:                                                                   *
  134. *                                                                              *
  135. *   class T                                                                    *
  136. *******************************************************************************/
  137. public:
  138. /*------------------------ Constructors and Destructor ------------------------
  139. | You can construct instances of this class in the following ways:             |
  140. |                                                                              |
  141. |   -  The primary constructor accepts a pointer to an instance of the         |
  142. |      referenced class.  This also serves as the default constructor
  143. |      (defaulting the pointer argument to 0).                                                         |
  144. |                                                                              |
  145. |   -  The copy constructor is provided to ensure that the reference counts    |
  146. |      for both the source and target referents are maintained properly.       |
  147. |                                                                              |
  148. | The destructor ensures that the referenced object is de-referenced.         |
  149. ------------------------------------------------------------------------------*/
  150.   IReference ( T *p = 0 )
  151.     : referent( p )
  152.     {
  153.     }
  154.  
  155.   IReference ( const IReference<T> &source )
  156.     : referent( source.referent )
  157.     {
  158.     if ( source.referent )
  159.       source.referent -> addRef();
  160.     }
  161.  
  162.   ~IReference ( )
  163.     {
  164.     if ( referent )
  165.       referent->removeRef();
  166.     }
  167.  
  168. /*------------------------------- Assignment -----------------------------------
  169. | This class defines the following assignment operator:                        |
  170. |   operator = - Assignment operator; one IReference can be assigned to        |
  171. |                another or a pointer to the referenced type can be assigned.  |
  172. ------------------------------------------------------------------------------*/
  173. IReference<T>
  174.  &operator = ( const IReference<T> &source )
  175.   {
  176.   if ( source.referent )
  177.     source.referent -> addRef();
  178.   if ( referent )
  179.     referent -> removeRef();
  180.   referent = source.referent;
  181.   return *this;
  182.   }
  183. IReference<T>
  184.  &operator = ( T *p )
  185.   {
  186.   if ( p )
  187.     p -> addRef();
  188.   if ( referent )
  189.     referent -> removeRef();
  190.   referent = p;
  191.   return *this;
  192.   }
  193.  
  194. /*-------------------------------- Accessors -----------------------------------
  195. | Use these operators to access the referenced object.                         |
  196. | Their effect is to make an IReference usable much like a normal pointer.     |
  197. |   operator -> - Pointer operator that provides access to the referenced      |
  198. |                 object.                                                      |
  199. |   operator *  - Pointer de-reference operator that provides access to the    |
  200. |                 referenced object.                                           |
  201. |   operator T* - Returns the referent.                                        |
  202. ------------------------------------------------------------------------------*/
  203. T
  204.  *operator -> ( ) const
  205.    {
  206.    if ( !referent )
  207.      ITHROWLIBRARYERROR(IC_NULL_IREFERENCE, IErrorInfo::invalidRequest, IException::recoverable);
  208.    return referent;
  209.    }
  210. T
  211.  &operator *  ( ) const
  212.    {
  213.    if ( !referent )
  214.      ITHROWLIBRARYERROR(IC_NULL_IREFERENCE, IErrorInfo::invalidRequest, IException::recoverable);
  215.    return *referent;
  216.    }
  217.  
  218.  operator T* ( ) const
  219.  {
  220.    return (referent);
  221.  }
  222. private:
  223. /*--------------------------------- PRIVATE ----------------------------------*/
  224. T
  225.  *referent;
  226.  
  227. }; // template class IReference
  228.  
  229. /*----------------------------------------------------------------------------*/
  230. /* Resume compiler default packing.                                           */
  231. /*----------------------------------------------------------------------------*/
  232. #pragma pack()
  233.  
  234. #endif /* _IREFCNT_ */
  235.