CountedPtr.h

00001 #ifndef _CountedPtr_h
00002 #define _CountedPtr_h
00003 
00005 //*/
00006 //template<class T>
00007 //struct Counter {
00008 //    Counter(T* pointer)
00009 //        : mPointer(pointer), mCount(1)
00010 //        { }
00011 //
00012 //    T*  mPointer;
00013 //    int mCount;
00014 //};
00015 
00016 
00022 template <class T>
00023 class CountedPtr
00024 {
00025 
00026     // TODO: dodać friend dla CountedPtr na inne typy wskaźników i ukryć to, co
00027     // nie powinno być na wierzchu.
00028 
00029 public:
00030 // LIFECYCLE
00031 
00034     explicit CountedPtr(T* pointer = NULL)
00035         : mpCount(NULL), mpObject(NULL)
00036     {
00037         if (pointer != NULL)
00038         {
00039             mpObject = pointer;
00040             mpCount  = new unsigned;
00041             *mpCount = 1;
00042         }
00043     }
00044 
00049     CountedPtr(std::auto_ptr<T> aPointer)
00050         : mpCount(new unsigned)
00051     {
00052         // Ponieważ new może wyrzucić wyjątek, to z aPointer.release czekamy, aż
00053         // alokacja się powiedzie.
00054         *mpCount = 1;
00055         mpObject = aPointer.release();
00056     }
00057 
00060     CountedPtr(const CountedPtr& from)
00061         : mpCount(NULL), mpObject(NULL)
00062     {
00063         Acquire(from.mpObject, from.mpCount);
00064     }
00065 
00070     template<class T2>
00071     CountedPtr(std::auto_ptr<T2> aPointer)
00072         : mpCount(new unsigned)
00073     {
00074         // Ponieważ new może wyrzucić wyjątek, to z aPointer.release czekamy, aż
00075         // alokacja się powiedzie.
00076         *mpCount = 1;
00077         mpObject = aPointer.release();
00078     }
00079 
00082     template<class T2>
00083     CountedPtr(const CountedPtr<T2>& cPointer)
00084         : mpCount(NULL), mpObject(NULL)
00085     {
00086         Acquire(cPointer.mpObject, cPointer.mpCount);
00087     }
00088 
00089 
00092     ~CountedPtr()
00093     {
00094         Drop();
00095     }
00096 
00097 // OPERATORS
00098 
00101     CountedPtr& operator=(const CountedPtr& from) throw()
00102     {
00103         if (this != &from)
00104         {
00105             Drop();
00106             Acquire(from.mpObject, from.mpCount);
00107         }
00108 
00109         return *this;
00110     }
00111 
00116     CountedPtr& operator=(std::auto_ptr<T> aPointer) throw()
00117     {
00118         Reset(aPointer.release());
00119 
00120         return *this;
00121     }
00122 
00125     template <class T2>
00126     CountedPtr& operator=(const CountedPtr<T2>& from) throw()
00127     {
00128         if (this != &from)
00129         {
00130             Drop();
00131             Acquire(from.mpCounter);
00132         }
00133 
00134         return *this;
00135     }
00136 
00139     T& operator*() const throw()
00140     {
00141         assert(mpCount  != NULL);
00142         assert(mpObject != NULL);
00143 
00144         return *mpObject;
00145     }
00146 
00149     T* operator->() const throw()
00150     {
00151         assert(mpCount != NULL);
00152 
00153         return mpObject;
00154     }
00155 
00156 // OPERATIONS
00157 
00163     void Reset(T* pNew)
00164     {
00165         Drop();
00166         if (pNew != NULL)
00167         {
00168             mpObject = pNew;
00169             mpCount  = new unsigned;
00170             *mpCount = 1;
00171         }
00172     }
00173 
00174 // ACCESS
00175 
00178     T* Get() const
00179     {
00180         return mpObject;
00181     }
00182 
00185     void Acquire(T* pObject, unsigned* pCount) throw()
00186     {
00187         assert (mpObject == NULL);
00188         assert (mpCount == NULL);
00189 
00190         if (pCount != NULL)
00191         {
00192             mpObject = pObject;
00193             mpCount = pCount;
00194             ++(*mpCount);
00195         }
00196     }
00197 
00202     template<class T2>
00203     void Acquire(T2* pObject, unsigned* pCount) throw()
00204     {
00205         assert (mpObject == NULL);
00206         assert (mpCount == NULL);
00207 
00208         if (pCount != NULL)
00209         {
00210             mpObject = pObject;
00211             mpCount = pCount;
00212             ++(*mpCount);
00213         }
00214     }
00215 
00216 
00219     void Drop()
00220     {
00221         if (mpCount != NULL)
00222         {
00223             --(*mpCount);
00224             if (*mpCount == 0)
00225             {
00226                 delete mpObject;
00227                 delete mpCount;
00228             }
00229             mpCount = NULL;
00230             mpObject = NULL;
00231         }
00232     }
00233 
00234     unsigned*   mpCount;
00235     T*          mpObject;
00236 protected:
00237 private:
00238 };
00239 
00240 #endif

Wygenerowano Fri Sep 29 21:04:47 2006 dla EduOptim2 programem  doxygen 1.4.6