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__