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

CdbCPtr.hh

Go to the documentation of this file.
00001 #ifndef CDB_CPTR_HH
00002 #define CDB_CPTR_HH
00003 
00004 // File and Version Information:
00005 //      $Id: CdbCPtr.hh,v 1.7 2004/08/06 05:54:14 bartoldu Exp $
00006 
00007 #include "CdbBase/CdbCommon.hh"
00008 #include "CdbBase/CdbCPtrBase.hh"
00009 #include "CdbBase/CdbDoNotClosePolicy.hh"
00010 
00011 #include <iostream>
00012 
00013 /// Smart counted pointer class supporting the automatic close policy.
00014 /**
00015   * The is a non-intrusive implementation that allocates an additional
00016   * int and pointer for every counted object.
00017   *
00018   * The close policy is provided through an additional policy class.
00019   * The only method we expect from the policy class is:
00020   *
00021   * @code
00022   *
00023   *     static void CLOSE_POLICY::close( P* ptr );
00024   * @endcode
00025   *
00026   * It's up to the developer of this class how it will interract
00027   * with the pointee object in order to "close" its instances.
00028   *
00029   * By default, the "CdbDoNotClosePolicy" policy class will be used.
00030   */
00031 
00032 template < class P, class CLOSE_POLICY = CdbDoNotClosePolicy<P> >
00033 class CdbCPtr : private CdbCPtrBase<P> {
00034 
00035 public:
00036 
00037   /// This is the type of objects pointed through this smart pointer
00038   /**
00039     * The concrete type will be available at the instantiation of the current
00040     * template class.
00041     */
00042     typedef P element_type;
00043 
00044   /// This is the type of the close policy
00045   /**
00046     * The concrete type will be available at the instantiation of the current
00047     * template class.
00048     */
00049     typedef CLOSE_POLICY close_policy;
00050 
00051   /// The constructor
00052   /**
00053     * This is the normal and default constructor. It will take the ownership
00054     * of specified pointer and initialize the internal counter to 1 if a non-null
00055     * pointer is passed.
00056     */
00057     CdbCPtr( P* ptr = 0 );
00058 
00059   /// The copy constructor
00060   /**
00061     * This constructor initializes the current instance to share
00062     * the counter object with the specified pointer. This will also increment
00063     * by 1 the number of smart pointers pointing onto the poentee, if this
00064     * is not a 0 pointer.
00065     */
00066     CdbCPtr( const CdbCPtr<P,CLOSE_POLICY>& thePtr );
00067 
00068   /// The destructor
00069   /**
00070     * Decrement the number of clients for the pointee. If we're the last
00071     * smart pointer then:
00072     *
00073     * - close the object. This operation is done through the supplied (as
00074     *   a template parameter) policy class.
00075     *
00076     * - destroy the pointee. Here we're assuming that its destructor
00077     *   is available for us.
00078     */
00079     ~CdbCPtr( );
00080 
00081   /// Asignment operator
00082   /**
00083     * Drop the currently hold pointee.
00084     * And borrow the counter object from the right-hand smart pointer object
00085     * and increment by 1the number of clients for the pointee object
00086     * (if this is not the 0).
00087     */
00088     CdbCPtr& operator=( const CdbCPtr<P,CLOSE_POLICY>& thePtr );
00089 
00090   /// Asignment operator
00091   /**
00092     * Drop the currently hold pointee.
00093     * And take ownership ower the specified pointee object. Set the total
00094     * number of its clients to 1.
00095     */
00096     CdbCPtr& operator=( P* ptr );
00097 
00098   /// Dereference operator
00099   /**
00100     * Return a reference to the pointed object.
00101     *
00102     * Here is a trivial example on how to use this operator:
00103     *
00104     * @code
00105     *   // This is a simple class whose objects will be
00106     *   // pointed through the smart pointer.
00107     *     class A ... {
00108     *     public:
00109     *         void foo( );
00110     *     };
00111     *
00112     *   // Initialize smart pointer to point onto a new object.
00113     *   // Remember, that the smart pointer will take ownership
00114     *   // over this object.
00115     *     CdbCPtr<A,SomePolicy> aPtr( new A( ));
00116     *
00117     *   // Do something usefull
00118     *     (*Aptr).foo( );   // 
00119     * @endcode
00120     */
00121     P& operator*( ) const;
00122 
00123   /// The arrow operator
00124   /**
00125     * This operator is meant to provide access to the members of the pointed
00126     * object in the same way if it were the regular pointer.
00127     *
00128     * Here is a trivial example on how to use this operator:
00129     *
00130     * @code
00131     *   // This is a simple class whose objects will be
00132     *   // pointed through the smart pointer.
00133     *     class A ... {
00134     *     public:
00135     *         void foo( );
00136     *     };
00137     *
00138     *   // Initialize smart pointer to point onto a new object.
00139     *   // Remember, that the smart pointer will take ownership
00140     *   // over this object.
00141     *     CdbCPtr<A,SomePolicy> aPtr( new A( ));
00142     *
00143     *   // Do something usefull
00144     *     APtr->foo( );   // 
00145     * @endcode
00146     */
00147     P* operator->( ) const;
00148 
00149   /// The comparision operator
00150   /**
00151     * This operator will compare two smart pointers if they both point
00152     * onto the same object. It will also return true if both smart pointers
00153     * are pointinig to 0.
00154     *
00155     * An example:
00156     *
00157     * @code
00158     *   // Initialize two smart pointers in different ways: the first one
00159     *   // will point to 0, and the second one - to a real object of class A.
00160     *     CdbCPtr<A,...> aNullPtr;
00161     *     CdbCPtr<A,...> aSomePtr( new A( ));
00162     *
00163     *   // Compare the pointers
00164     *     if( aSomePtr == aNullPtr ) {
00165     *         ...
00166     *     }
00167     * @endcode
00168     *
00169     * @return the result of comparision
00170     */
00171     bool operator==( const CdbCPtr<P,CLOSE_POLICY>& thePtr ) const;
00172 
00173   /// The not-equal operator
00174   /**
00175     * @see CdbCPtr::operator==( CdbCPtr& thePtr )
00176     */
00177     bool operator!=( const CdbCPtr<P,CLOSE_POLICY>& thePtr ) const;
00178 
00179   /// The comparision operator
00180   /**
00181     * This operator will compare a smart pointer with a regular pointer
00182     * to see if the smart one points to the same object as the regular one.
00183     * It will also return true if both pointers are pointinig to 0.
00184     *
00185     * Note, that the primarily use of this operator is to check if the smart
00186     * pointer is pointing to 0. The other cases should not be possible
00187     * because smart pointer must be the only way to point objects.
00188     *
00189     * It's also important to note, that because of the restricted syntax of
00190     * the comparision operator in the class's scope, it's only possible to specify
00191     * the regular pointer on the righ-hand side of the comparision as it's shown
00192     * in a code example below. The reverse order can be added later for concrete
00193     * instantiations of the smart pointer.
00194     *
00195     * An example:
00196     *
00197     * @code
00198     *   // Initialize a smart pointer to a real object of class A.
00199     *     CdbCPtr<A,...> aSomePtr( new A( ));
00200     *     A*             ptr = ...;
00201     *
00202     *   // Compare this pointer with specified pointer.
00203     *     if( aSomePtr == ptr ) {
00204     *         ...
00205     *     }
00206     * @endcode
00207     *
00208     * @return the result of comparision
00209     */
00210     bool operator==( const P* ptr ) const;
00211 
00212   /// The not-equal operator
00213   /**
00214     * @see CdbCPtr::operator==( const P* ptr )
00215     */
00216     bool operator!=( const P* ptr ) const;
00217 
00218   /// Explicit check if the pointer does point onto 0
00219   /**
00220     * This operation is equivalent to the "operator==((const P*)0 )".
00221     *
00222     * An example:
00223     *
00224     * @code
00225     *   // Initialize a smart pointer to a real object of class A.
00226     *     CdbCPtr<A,...> aSomePtr( new A( ));
00227     *
00228     *   // Compare this pointer with specified pointer.
00229     *     if( !aSomePtr.isNull( )) {
00230     *         // Okay, the pointer is pointing onto something usefull.
00231     *     }
00232     * @endcode
00233     *
00234     * @return the result of comparision
00235     */
00236     bool isNull( ) const;
00237 
00238   /// Return a non-const pointer to the pointed object
00239   /**
00240     * Note, that this does not transfer the ownership over the pointed object.
00241     */
00242     P* get( ) const;
00243 
00244   /// Check if this smart pointer is the only clients of the held pointer
00245   /**
00246     * @return true if this is the only client
00247     */
00248     bool unique( ) const;
00249 
00250 private:
00251 
00252   /// The nested class representing an internal counter.
00253   /**
00254     * Objects of these class are shared among multiple smart pointers
00255     * of the same type. The role of the counter class is to keep the pointer
00256     * to teh pointed object and to count the current numbver of clients - smart
00257     * pointers.
00258     */
00259     class Counter {
00260     public:
00261 
00262       /// The constructor
00263       /**
00264         * This is the normal and default constructor of the class
00265         * initializeing its context.
00266         */
00267         Counter( P* ptr = 0, unsigned count = 1 );
00268 
00269     public:
00270 
00271         P*       _ptr;
00272         unsigned _count;
00273     };
00274 
00275     Counter* _myCounter;
00276 
00277   /// Acquire the specified counter object
00278   /**
00279     * This method is meant to start sharing the specified counter
00280     * object and to increment the number of clients by 1.
00281     */
00282     void acquire( Counter* theCounter );
00283 
00284   /// Drop using the current counter object
00285   /**
00286     * This method is a way for a smart pointer object to get rid of
00287     * its current contex. This will lead to the reduction by 1 of the number
00288     * of current clients of the pointee object and possible closure
00289     * and subsequent destruction of this object if we were the last client.
00290     */
00291     void release( );
00292 };
00293 
00294 /// The missing equality operator for the smart pointer
00295 /**
00296   * This operator allows to compare a smart pointer with a regular one
00297   * while having the regular one on the left hand side of the comparision
00298   * expression.
00299   *
00300   * This makes possible the following use case:
00301   *
00302   * @code
00303   *     CdbXyzPtr thePtr = ...;
00304   *     if( 0 == thePtr ) ...
00305   * @endcode
00306   */
00307 
00308 template < class P, class CLOSE_POLICY >
00309 bool
00310 operator==( const P*                       ptr,
00311             const CdbCPtr<P,CLOSE_POLICY>& thePtr )
00312 {
00313     return thePtr == ptr;
00314 }
00315 
00316 /// The missing non-equal operator for the smart pointer
00317 /**
00318   * See the previously defined global equaty operator
00319   */
00320 template < class P, class CLOSE_POLICY >
00321 bool
00322 operator!=( const P*                       ptr,
00323             const CdbCPtr<P,CLOSE_POLICY>& thePtr )
00324 {
00325     return thePtr != ptr;
00326 }
00327 
00328 #ifdef     BABAR_COMP_INST
00329 #include "CdbBase/CdbCPtr.cc"
00330 #endif  // BABAR_COMP_INST
00331 
00332 #endif // CDB_CPTR_HH

Generated on Mon Dec 5 18:22:05 2005 for CDB by doxygen1.3-rc3