Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

/magnus/back_end/global/ObjectOf.h

Go to the documentation of this file.
00001 /*
00002  *   $Id: ObjectOf.h,v 1.4 1999/11/23 20:34:52 bormotov Exp $
00003  */
00004 
00005 // Copyright (C) 1994 The New York Group Theory Cooperative
00006 // See magnus/doc/COPYRIGHT for the full notice.
00007 
00008 // Contents: Definition of class ObjectOf
00009 //
00010 // Principal Author: Stephane Collart
00011 //
00012 // Description:
00013 //
00014 // * A representation pointer wrapper.
00015 // * Provided for backward compatibility.
00016 //
00017 // Usage:
00018 //
00019 // * ObjectOf<MyClassRep> assumes that
00020 //   1) MyClassRep is derived from RefCounter
00021 //   2) MyClassRep has a member MyClassRep* clone(); returning a (logical)
00022 //      deep copy of *this
00023 //
00024 // * Derive MyClass from ObjectOf<MyClassRep>
00025 //
00026 // @stc see comments in PureRep
00027 //
00028 // Example:
00029 //
00030 // Status: Complete
00031 //
00032 // Bugs:
00033 //
00034 // * ObjectOf does not prevent abuse by e.g. deriving further classes and reusing
00035 //   them to wrap derived representations
00036 //
00037 // Questions:
00038 //
00039 // * Class A has pseudo-virtual method m(...)
00040 //
00041 //   The actual effect of a.m() is not known at the time
00042 //   of calling. This effect may be
00043 //   1) create a new representation for a to adopt in lieu of
00044 //      the old one
00045 //   2) take some extant representation for a to adopt in lieu
00046 //      of its old one
00047 //   3) modify the representation of a in place
00048 //
00049 //   1) means a single call of delref() on the old rep
00050 //   2) means delref() on the old rep and addref() on the new
00051 //   3) means a's rep must if necessary be replaced by an unshared
00052 //   clone before modification begins
00053 //
00054 //   Requirement: fix this up in a `nice', reusable way
00055 //
00056 // Revision History:
00057 //
00058 
00059 #ifndef _OBJECT_OF_H_
00060 #define _OBJECT_OF_H_
00061 
00062 
00063 #include <iostream.h>
00064 #include "RefCounter.h"
00065 
00066 
00067 /*! 
00068 Description:
00069 
00070  A representation pointer wrapper.
00071  Provided for backward compatibility.
00072 
00073  Usage:
00074 
00075  ObjectOf<MyClassRep> assumes that
00076   1) MyClassRep is derived from RefCounter
00077   2) MyClassRep has a member MyClassRep* clone(); returning a (logical)
00078      deep copy of *this
00079 
00080  Derive MyClass from ObjectOf<MyClassRep> see comments in PureRep.
00081 */
00082 template<class Rep> class ObjectOf
00083 {
00084 
00085 public:
00086 
00087   ///////////////////////////////////////////////////////////
00088   //                                                       //
00089   // Constructors:                                         //
00090   //                                                       //
00091   ///////////////////////////////////////////////////////////
00092 
00093   ObjectOf( const ObjectOf& o ) { theRep = o.theRep; theRep->addRef(); }
00094   //!< Copy constructor.
00095   /*!< Assignes representation object of the parameter and increases
00096     its reference count */
00097 
00098   ~ObjectOf() { if (theRep->lastRef()) delete theRep; else theRep->delRef(); }
00099   /*!< Decreases referense copunt. If last one than delete the representation object
00100    */  
00101 
00102   ///////////////////////////////////////////////////////////
00103   //                                                       //
00104   // Standard Operators:                                   //
00105   //                                                       //
00106   ///////////////////////////////////////////////////////////
00107 
00108   ObjectOf& operator = ( const ObjectOf& o )
00109   {
00110         o.theRep->addRef();
00111     if ( theRep->lastRef() ) delete theRep; else theRep->delRef();
00112     theRep = o.theRep;
00113     return *this;
00114   }
00115   /*!< Assignment operator.
00116     Increment number of refrences of 'o'. If '*this' was the last copy
00117     deletes reference object */ 
00118 
00119   ///////////////////////////////////////////////////////////
00120   //                                                       //
00121   // Debugging Stuff:                                      //
00122   //                                                       //
00123   ///////////////////////////////////////////////////////////
00124 
00125   #ifdef DEBUG
00126   void debugPrint( ostream& ostr ) {
00127         ostr << "this : " << this << "; theRep : " << theRep << "; xrefs : "
00128                  << look()->nxrefs();
00129   }
00130 
00131   //friend int main( );
00132   #endif
00133 
00134 
00135 protected:
00136 
00137   ///////////////////////////////////////////////////////////
00138   //                                                       //
00139   // Representation Access:                                //
00140   //                                                       //
00141   ///////////////////////////////////////////////////////////
00142 
00143   const Rep* look( ) const { return theRep; }
00144   /*!< Returns a constant pointer to its representation object
00145     For safe read-only access. */
00146 
00147   Rep* enhance( ) const { return theRep; }
00148   /*!< Returns a pointer to its representation object
00149     \warning for altering an object without triggering cloning.
00150    Use to change theRep without altering semantics.
00151   */
00152 
00153   Rep* change( ) {
00154     if ( theRep->lastRef() ) return theRep;
00155     else { theRep->delRef(); return theRep = (Rep*)theRep->clone(); }
00156   }
00157   /*!< Returns a pointer to its representation object
00158     For safe read/write access. */
00159 
00160   void acquireRep( const Rep* rep )
00161   {
00162     ((Rep*&)rep)->addRef();
00163         // cast away physical constness to permit logically const
00164         // incrementation of ref count
00165     if ( theRep->lastRef() ) delete theRep; else theRep->delRef();
00166     theRep = ((Rep*&)rep);
00167         // cast away physical constness of representation for
00168         // acquisition through new object; semantics of look() and
00169         // and change() guarantee that logical constness is maintained
00170   }
00171   /*!< Special `assignment-like' member: to permit an object to acquire
00172    another's representation consistently
00173    useful in delegation of object-level methods */
00174 
00175   ///////////////////////////////////////////////////////////
00176   //                                                       //
00177   // Special Constructors:                                 //
00178   //                                                       //
00179   ///////////////////////////////////////////////////////////
00180 
00181   ObjectOf( Rep* newrep ) { theRep = newrep; }
00182   /*!< Special Constructor To wrap new representations */
00183 
00184 private:
00185 
00186   ///////////////////////////////////////////////////////////
00187   //                                                       //
00188   // Data Members:                                         //
00189   //                                                       //
00190   ///////////////////////////////////////////////////////////
00191 
00192   Rep* theRep;
00193   /*!< Pointer to the representation object */
00194 
00195   ///////////////////////////////////////////////////////////
00196   //                                                       //
00197   // Safety:                                               //
00198   //                                                       //
00199   ///////////////////////////////////////////////////////////
00200 
00201   void force_derivation( ) { RefCounter* rc = theRep; }
00202   /*!< With this member RefCounter is forced to be 
00203   an accessible base class of Rep */
00204 
00205 };
00206 
00207 
00208 #endif

Generated at Tue Jun 19 09:49:36 2001 for Magnus Classes by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001