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

SmartPtr.h

Go to the documentation of this file.
00001 
00039 #ifndef __SMART_PTR_H__
00040 #define __SMART_PTR_H__
00041 
00042 #include "Debug.h"
00043 
00062 template<class T> class SmartPtr
00063 {
00064         struct DATAREF {
00065                 T* pData;
00066                 int nLinks;
00067                 DATAREF() { nLinks = 1; }
00068         };
00069 
00070         DATAREF* ptr;
00071 
00072 public:
00073         
00074         SmartPtr() { 
00075                 ptr = new DATAREF;
00076                 ptr->pData = NULL;
00077         }
00078 
00079         SmartPtr(T* p) { 
00080                 ptr = new DATAREF; 
00081                 ptr->pData = p; 
00082         }
00083 
00084         SmartPtr(const T* p) {
00085                 ptr = new DATAREF;
00086                 ptr->pData = (T*)p; //Supposely it's safe to discard 'const' here
00087 
00088                 // There is someone else ponting at this object, so add one ref
00089                 // s.t. we don't destroy the actual data in the destructor.
00090                 ptr->nLinks++;
00091         }
00092         
00093         SmartPtr(const T& obj) {
00094                 ptr = new DATAREF;
00095                 ptr->pData = new T;
00096                 *ptr->pData = obj; // Clone object
00097         }
00098 
00099         SmartPtr(const SmartPtr<T>& x)  { 
00100                 x.ptr->nLinks++;
00101                 ptr = x.ptr;
00102         }
00103 
00104         ~SmartPtr() { 
00105                 if (--ptr->nLinks == 0) {
00106                         if (ptr->pData)
00107                                 delete ptr->pData;
00108                         delete ptr;
00109                 } 
00110         }       
00111 
00112         const T* operator->() const { 
00113                 return ptr->pData; 
00114         }
00115 
00116         bool operator==(const SmartPtr<T>& rhs) const
00117         {
00118                 return ptr->pData == rhs.ptr->pData;
00119         }
00120 
00121         bool IsNull() const
00122         {
00123                 return ptr->pData == NULL;
00124         }
00125 
00126         T* operator->() {
00127                 if (ptr->nLinks > 1) {
00128                         ptr->nLinks--;
00129                         T* p = ptr->pData->CreateObject();
00130                         *p = *ptr->pData;
00131 
00132                         ptr = new DATAREF;
00133                         ptr->pData = p;
00134                         
00135                         WARNING(true, "possible not desired copy of data");
00136                 }
00137 
00138                 return ptr->pData; 
00139         }
00140 
00141         SmartPtr<T>& operator=(const SmartPtr<T>& rhs) {
00142                 rhs.ptr->nLinks++;      // protect against 'x = x'
00143                 
00144                 if (--ptr->nLinks == 0) {
00145                         delete ptr->pData;
00146                         delete ptr;
00147                 }
00148 
00149                 ptr = rhs.ptr;
00150                 return *this;
00151         }
00152 
00153         SmartPtr<T>& operator=(T* rhs) {
00154         
00155                 if (ptr->nLinks > 1)
00156                 {
00157                         ptr->nLinks--;
00158                         ptr = new DATAREF;
00159                 }
00160                 else
00161                         delete ptr->pData;
00162 
00163                 ptr->pData = rhs;
00164                 return *this;
00165         }
00166 
00167         int Links() const { return ptr->nLinks; }
00168 
00169         operator const T*() const { return ptr->pData; }
00170         operator const T&() const { return *ptr->pData; }
00171         operator const unsigned long() const { return (const unsigned long) ptr->pData; }
00172 
00173         T& operator*()  { return *operator->(); }
00174 
00175 #ifdef WIN32
00176         friend ostream& operator<<(ostream& os, const SmartPtr<T>& x);
00177         friend istream& operator>>(istream& is, SmartPtr<T>& x);
00178 #else
00179         friend ostream& operator<< <>(ostream& os, const SmartPtr<T>& x);
00180         friend istream& operator>> <>(istream& is, SmartPtr<T>& x);
00181 #endif //WIN32
00182 };
00183 
00184 template<class T>
00185 ostream& operator<<(ostream& os, const SmartPtr<T>& x) { return os << *(x.ptr->pData); }
00186 
00187 template<class T>
00188 istream& operator>>(istream& is, SmartPtr<T>& x) { return is >> *(x.ptr->pData); }
00189 
00190 #endif //__SMART_PTR_H__

Generated on Sat Nov 13 11:21:26 2004 for Noisy DAG Matcher by doxygen1.2.18