home *** CD-ROM | disk | FTP | other *** search
- /*==============================================================================
- Module Name: irefcnt.hpp
-
- Description:
- Header file for generic "reference counting" classes.
-
- Copyright: (C) Copyright IBM Corporation 1992
- All Rights Reserved
- Licensed Materials = Property of IBM
-
- Usage:
- This header should be #include-d in the header file for
- classes that are reference counted (derived from IRefCounted)
- or serve as references (derived from the IReference template
- class).
-
- Notes:
-
- Related Topics:
-
- History:
- flag yymmdd who description
- ---- ------ --- -----------------------------------------------------------
- 920826 law Initial
- 920916 law Remove "new T" as default on IReference<T>::IReference<T>
- ==============================================================================*/
- #if !defined( _IREFCNT_ )
- #define _IREFCNT_
-
- /*------------------------------------------------------------------------------
- Class Name: IReference
-
- Description:
- Template class inherited from by classes serving as references to
- some "reference counted" class.
-
- Usage:
- This template class is derived from by classes wishing to serve
- as "referernces." Instances of such classes will serve as "smart
- pointers" to instances of the referenced class. Creation of
- instances of this class will increment the use count of the
- referenced object. Destruction of the object will cause the
- use count of the referenced object to be decremented.
-
- Typically, this class will only be referenced explicitly as a
- public base class of the class that provides the additional
- capability of the reference class. For example,
- :xmp.
- class Foo;
- class FooRef : public IReference<Foo> {
- // Additional FooRef functions...
- };
- :exmp.
-
- The reference counted class provided as the template argument should be
- derived from class IRefCounted.
-
- To construct an IReference, one must provide a pointer to an instance
- of the referenced (reference counted) class. By implication, then, all
- constructors of the "real" reference class (derived from IReference<T>)
- must provide such a pointer. Otherwise, the reference class need take
- on no additional responsibilities.
-
- Notes:
- 1. The semantics of such reference/referent classes perhaps have
- some subtle complexities. Care must be taken in any case where
- either the reference or the referent behave in any sort of
- extraordinary fashion.
-
- 2. A class can also serve as a reference by having as a data member
- and instance of class IReference<T>.
-
- 3. All members of class IReference are public in order to permit
- the usage described in Note 2.
-
- Related Topics:
- IRefCounted
- ------------------------------------------------------------------------------*/
- template < class T > class IReference {
-
- public:
-
- /*------------------------------------------------------------------------------
- Function Name: IReference :: IReference
-
- Description:
- Standard constructor for template class IReference.
-
- Syntax:
- IReference<T> tref( t );
-
- Parameters:
- T - (template arg) name of class being referenced
- t - pointer to instance of class T (or 0); the default
- argument will be 0
-
- Return Values:
- tref - new reference to instance of class T pointed to by t
-
- Usage:
- Usually, the real reference class is derived from IReference<T>.
- Because of this, this constructor is most often invoked from the
- constructor initializer list specified in the real reference
- class's constructor(s).
-
- Exceptions:
-
- Notes:
- 1. This constructor does not increment the use count of the
- referenced object. The assumption is that the reference
- count of this object will be adjusted as necessary outside
- of the constructor. Note that this corresponds to the default
- behavior of class IRefCounted.
-
- Related Topics:
- ------------------------------------------------------------------------------*/
- IReference ( T *p = 0 )
- : referent( p )
- {
- }
-
- /*------------------------------------------------------------------------------
- Function Name: IReference :: IReference
-
- Description:
- Copy constructor for template class IReference.
-
- Syntax:
- IReference<T> tref2( tref1 );
-
- Parameters:
- T - (template arg) name of class being referenced
- tref1 - reference to const instance of IReference<T>; the
- resulting reference will be constructed to refer to
- the same object as does this argument
-
- Return Values:
- tref2 - new reference to instance of class T referenced by tref1
-
- Usage:
- Usually, the real reference class is derived from IReference<T>.
- Because of this, this constructor is most often invoked from the
- (default) copy constructor of this real reference class. In most
- cases, the default copy constructor will suffice. If the real
- reference class implements an explicit copy constructor then
- that constructor should invoke this one via its initializer list.
-
- Exceptions:
-
- Notes:
-
- Related Topics:
- ------------------------------------------------------------------------------*/
- IReference ( const IReference<T> &source )
- {
- if ( source.referent )
- source.referent -> addRef();
- referent = source.referent;
- }
-
- /*------------------------------------------------------------------------------
- Function Name: IReference :: ~IReference
-
- Description:
- Destructor for the reference counting class.
-
- Notes:
- 1. The destructor simply decrements the use count of the referenced
- object.
-
- Related Topics:
- ------------------------------------------------------------------------------*/
- ~IReference ( )
- {
- if ( referent )
- referent->removeRef();
- }
-
- /*------------------------------------------------------------------------------
- Function Name: IReference :: operator =
-
- Description:
- Assignment operator for the template class IReference.
-
- Syntax:
- tref2 = tref1;
-
- Parameters:
- tref1 - instance of class IReference<T> whose referenced object is
- now to be referenced by tref1 (*this)
-
- Return Values:
- tref2 - reference to the object being assigned to
-
- Usage:
- This function is provided in order to permit "reference" objects to
- be assigned to while still preserving the reference count of the
- referenced objects.
-
- Exceptions:
-
- Notes:
- 1. Care is taken to increment the source object's use count prior to
- decrementing the use count of the object referenced by the
- reference being assigned to. This produces reliable behavior in
- case a reference is assigned to itself.
-
- Related Topics:
- ------------------------------------------------------------------------------*/
- IReference<T>
- &operator = ( const IReference<T> &source )
- {
- if ( source.referent )
- source.referent -> addRef();
- if ( referent )
- referent -> removeRef();
- referent = source.referent;
- return *this;
- }
-
- /*------------------------------------------------------------------------------
- Member Name: IReference :: referent
-
- Description:
- Data member pointing to referenced object.
-
- Usage:
- This member is utilized by the reference class to obtain access
- to the referenced object.
-
- Notes:
- 1. The value of this member can be 0 (indicating there is no
- referenced object).
-
- Related Topics:
- ------------------------------------------------------------------------------*/
- T
- *referent;
- }; // template class IReference
-
- /*------------------------------------------------------------------------------
- Class Name: IRefCounted
-
- Description:
- Base "reference counted" class.
-
- Usage:
- This class is made a public base class for any class that is to be
- "reference counted." Such inheritance conveys the functional
- characteristics of maintaining a count of all "references" to them
- and deferring destruction until all such references are destroyed.
-
- Typically, use of this class is paired with corresponding use of
- IReference<T> (where T is a subclass of IRefCounted).
-
- Notes:
-
- Related Topics:
- IReference
- ------------------------------------------------------------------------------*/
- class IRefCounted {
-
- public:
-
- /*------------------------------------------------------------------------------
- Function Name: IRefCounted :: addRef
-
- Description:
- Add new reference to the reference-counted object.
-
- Syntax:
- referent -> addRef();
-
- Parameters:
-
- Return Values:
-
- Usage:
- This function must be invoked whenever a new reference to the
- reference-counted object is created.
-
- Examples of such situations are the copy constructor and assignment
- operator for reference classes.
-
- Exceptions:
-
- Notes:
-
- Related Topics:
- removeRef
- ------------------------------------------------------------------------------*/
- void
- addRef ( )
- {
- useCount++;
- }
-
- /*------------------------------------------------------------------------------
- Function Name: IRefCounted :: removeRef
-
- Description:
- Remove a reference to the reference-counted object.
-
- Syntax:
- referent -> removeRef();
-
- Parameters:
-
- Return Values:
-
- Usage:
- This function must be invoked whenever a reference to the
- reference-counted object is destroyed.
-
- Examples of such situations are the destructor and assignment
- operator for reference classes.
-
- Exceptions:
-
- Notes:
- 1. If the reference count goes to zero, then the object is
- destroyed (and its storage released) via "delete this".
- Thus, this function must never be invoked while references
- to the object exist. The call to this function must be the
- last use of this object via the reference that is being
- removed.
-
- Related Topics:
- addRef
- ------------------------------------------------------------------------------*/
- void
- removeRef ( )
- {
- if ( --useCount == 0 )
- delete this;
- }
-
- protected:
-
- /*------------------------------------------------------------------------------
- Function Name: IRefCounted :: IRefCounted
-
- Description:
- Base constructor for reference counted classes.
-
- Usage:
- This constructor is invoked from within the initializer list of
- all derived class constructors.
-
- Exceptions:
-
- Notes:
- 1. The resulting reference counted object will have an
- initial use count of 1. As a consequence, the resulting pointer
- should be used to construct an instance of IReference<T> (so that
- the reference count will be decremented and the object destroyed
- at the appropriate time).
- 2. If the reference counted object is not allocated from free store
- (via new) then the use count will remain 1 and the object will
- be destructed in the normal fashion (i.e., when it goes out of
- scope).
-
- Related Topics:
- ------------------------------------------------------------------------------*/
- IRefCounted ( )
- : useCount( 1 )
- {}
-
- /*------------------------------------------------------------------------------
- Function Name: IRefCounted :: ~IRefCounted
-
- Description:
- Destructor for reference counted class.
-
- Exceptions:
-
- Notes:
- 1. This destructor is virtual. This insures the deletion of the
- object within function removeRef() invokes the proper destructor.
-
- Related Topics:
- ------------------------------------------------------------------------------*/
- virtual
- ~IRefCounted ( )
- {}
-
- unsigned
- useCount;
- }; // Class IRefCounted
-
- #endif /* _IREFCNT_ */