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;
00087
00088
00089
00090 ptr->nLinks++;
00091 }
00092
00093 SmartPtr(const T& obj) {
00094 ptr = new DATAREF;
00095 ptr->pData = new T;
00096 *ptr->pData = obj;
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++;
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__