home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
cset21v1.zip
/
IBMCPP
/
IBMCLASS
/
IREFCNT.HPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-22
|
12KB
|
235 lines
#ifndef _IREFCNT_
#define _IREFCNT_
/*******************************************************************************
* FILE NAME: irefcnt.hpp *
* *
* DESCRIPTION: *
* Declaration of the class(es): *
* IRefCounted - Class providing generic "reference coutned" semantics *
* IReference - Template class serving as reference to IRefCounted objects *
* *
* COPYRIGHT: *
* Licensed Materials - Property of IBM *
* (C) Copyright IBM Corporation 1992, 1993 *
* All Rights Reserved *
* US Government Users Restricted Rights - Use, duplication, or disclosure *
* restricted by GSA ADP Schedule Contract with IBM Corp. *
* *
*******************************************************************************/
#ifndef _IVBASE_
#include <ivbase.hpp>
#endif
#ifndef _IEXCEPT_
#include <iexcept.hpp>
#endif
#ifndef _ICCONST_
#include <icconst.h>
#endif
/*----------------------------------------------------------------------------*/
/* Align classes on four byte boundary. */
/*----------------------------------------------------------------------------*/
#pragma pack(4)
class IRefCounted : public IVBase {
typedef IVBase
Inherited;
/*******************************************************************************
* The IRefCounted class is a public base class for any class that will be *
* reference counted. Such inheritance conveys the functional characteristics *
* of maintaining a count of all references to the object and deferring *
* destruction until all such references are destroyed. *
* *
* Objects of this class, by necessity, can only be allocated in free store. *
* This is enforced by making the destructor for this class protected. As a *
* result, only IRefCounted::removeRef and subclass destructors are permitted *
* to call IRefCounted::IRefCounted. Subclasses should make their destructors *
* protected, also. *
* *
* Typically, use of this class is paired with the corresponding use of *
* IReference<T> (where T is the subclass of IRefCounted). *
*******************************************************************************/
public:
/*--------------------------- Reference Counting -------------------------------
| Use these functions to manage the object's reference count: |
| addRef - Increments the reference count, such as when a new reference |
| is established. |
| removeRef - Decrements the reference count and deletes the object if it |
| goes to 0. |
| useCount - Returns the use count for the object. |
------------------------------------------------------------------------------*/
virtual void
addRef ( ),
removeRef ( );
unsigned
useCount ( ) const
{
return this->refCount;
}
protected:
/*------------------------- Constructor and Destructor -------------------------
| The constructor initializes the use count to 1. This presumes that the |
| newly constructed object's address is immediately used by some reference |
| (or functionally equivalent) object. The object that created the |
| IRefCounted object should not call addRef because it is already marked as |
| referenced by the constructor itself. |
| |
| The destructor is protected to disable creation of non-free store objects. |
------------------------------------------------------------------------------*/
IRefCounted ( );
~IRefCounted ( );
private:
/*--------------------------------- Private -----------------------------------*/
unsigned
refCount;
}; // class IRefCounted
template < class T >
class IReference : public IBase {
/*******************************************************************************
* The template class IReference is derived from classes that wish to serve as *
* references. Instances of such classes will serve as smart pointers to *
* instances of the referenced class. Creating 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: *
* *
* class Foo { .. }; *
* class FooRef : public IReference<Foo> { *
* // Additional FooRef functions... *
* }; *
* *
* The reference counted class provided as the template argument should be *
* derived from the IRefCounted class. It must have addRef and removeRef *
* member functions with equivalent semantics. *
* *
* To construct an IReference, you must provide a pointer to an instance of *
* the referenced (reference counted) class. 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. *
* *
* Customization (Template Arguments) *
* Class IReference is a template class instantiated with the template *
* arguments: *
* *
* class T *
*******************************************************************************/
public:
/*------------------------ Constructors and Destructor ------------------------
| You can construct instances of this class in the following ways: |
| |
| - The primary constructor accepts a pointer to an instance of the |
| referenced class. This also serves as the default constructor
| (defaulting the pointer argument to 0). |
| |
| - The copy constructor is provided to ensure that the reference counts |
| for both the source and target referents are maintained properly. |
| |
| The destructor ensures that the referenced object is de-referenced. |
------------------------------------------------------------------------------*/
IReference ( T *p = 0 )
: referent( p )
{
}
IReference ( const IReference<T> &source )
: referent( source.referent )
{
if ( source.referent )
source.referent -> addRef();
}
~IReference ( )
{
if ( referent )
referent->removeRef();
}
/*------------------------------- Assignment -----------------------------------
| This class defines the following assignment operator: |
| operator = - Assignment operator; one IReference can be assigned to |
| another or a pointer to the referenced type can be assigned. |
------------------------------------------------------------------------------*/
IReference<T>
&operator = ( const IReference<T> &source )
{
if ( source.referent )
source.referent -> addRef();
if ( referent )
referent -> removeRef();
referent = source.referent;
return *this;
}
IReference<T>
&operator = ( T *p )
{
if ( p )
p -> addRef();
if ( referent )
referent -> removeRef();
referent = p;
return *this;
}
/*-------------------------------- Accessors -----------------------------------
| Use these operators to access the referenced object. |
| Their effect is to make an IReference usable much like a normal pointer. |
| operator -> - Pointer operator that provides access to the referenced |
| object. |
| operator * - Pointer de-reference operator that provides access to the |
| referenced object. |
| operator T* - Returns the referent. |
------------------------------------------------------------------------------*/
T
*operator -> ( ) const
{
if ( !referent )
ITHROWLIBRARYERROR(IC_NULL_IREFERENCE, IErrorInfo::invalidRequest, IException::recoverable);
return referent;
}
T
&operator * ( ) const
{
if ( !referent )
ITHROWLIBRARYERROR(IC_NULL_IREFERENCE, IErrorInfo::invalidRequest, IException::recoverable);
return *referent;
}
operator T* ( ) const
{
return (referent);
}
private:
/*--------------------------------- PRIVATE ----------------------------------*/
T
*referent;
}; // template class IReference
/*----------------------------------------------------------------------------*/
/* Resume compiler default packing. */
/*----------------------------------------------------------------------------*/
#pragma pack()
#endif /* _IREFCNT_ */