00001 00002 // 00003 // Copyright (C) 2000 00004 // Ralf Westram 00005 // (Coded@ReallySoft.de) 00006 // 00007 // Permission to use, copy, modify, distribute and sell this software 00008 // and its documentation for any purpose is hereby granted without fee, 00009 // provided that the above copyright notice appear in all copies and 00010 // that both that copyright notice and this permission notice appear 00011 // in supporting documentation. Ralf Westram makes no 00012 // representations about the suitability of this software for any 00013 // purpose. It is provided "as is" without express or implied warranty. 00014 // 00015 // This code is part of my library. 00016 // You may find a more recent version at http://www.reallysoft.de/ 00017 // 00019 00020 #ifndef SMARTPTR_H 00021 #define SMARTPTR_H 00022 00023 #ifndef RS_ASSERT_H 00024 #include "rs_assert.h" 00025 #endif 00026 00027 namespace rs { 00028 00029 // -------------------------------------------------------------------------------- 00030 // SmartPointers 00031 // -------------------------------------------------------------------------------- 00032 00033 template <class T> class SmartPtr; 00034 00035 // -------------------------------------------------------------------------------- 00036 // class Counted 00037 // -------------------------------------------------------------------------------- 00039 template <class T> 00040 class Counted { 00041 private: 00042 unsigned counter; 00043 T *const pointer; 00044 00045 Counted(T *p) : counter(0), pointer(p) { assert(p); } 00046 ~Counted() { assert(counter==0); delete pointer; } 00047 00048 unsigned new_reference() { 00049 //cout << "new reference to pointer" << int(pointer) << " (now there are " << counter+1 << " references)" << "\n"; 00050 return ++counter; 00051 } 00052 unsigned free_reference() { 00053 //cout << "removing reference to pointer " << int(pointer) << " (now there are " << counter-1 << " references)\n"; 00054 assert(counter!=0); 00055 return --counter; 00056 } 00057 00058 friend class SmartPtr<T>; 00059 }; 00060 00061 template <class T> 00062 // -------------------------------------------------------------------------------- 00063 // class SmartPtr 00064 // -------------------------------------------------------------------------------- 00067 class SmartPtr { 00068 private: 00069 Counted<T> *object; 00070 00071 void Unbind() { 00072 if (object && object->free_reference()==0) delete object; 00073 object = 0; 00074 } 00075 public: 00077 SmartPtr() : object(0) {} 00078 00087 SmartPtr(T *p) { 00088 object = new Counted<T>(p); 00089 object->new_reference(); 00090 } 00091 00096 ~SmartPtr() {Unbind(); } 00097 00098 SmartPtr(const SmartPtr<T>& other) { 00099 object = other.object; 00100 if (object) object->new_reference(); 00101 } 00102 SmartPtr<T>& operator = (const SmartPtr<T>& other) { 00103 if (other.object) other.object->new_reference(); 00104 Unbind(); 00105 object = other.object; 00106 return *this; 00107 } 00108 00109 T *operator->() { assert(object); return object->pointer; } 00110 const T *operator->() const { assert(object); return object->pointer; } 00111 00112 T& operator*() { assert(object); return *(object->pointer); } 00113 const T& operator*() const { assert(object); return *(object->pointer); } 00114 00116 bool Null() const { return object==0; } 00117 00119 void SetNull() { Unbind(); } 00120 00127 SmartPtr<T> deep_copy() const { return SmartPtr<T>(new T(**this)); } 00128 00137 bool sameObject(const SmartPtr<T>& other) const { 00138 assert(object); 00139 assert(other.object); 00140 return object==other.object; 00141 } 00142 }; 00143 00144 template <class T> bool operator==(const SmartPtr<T>& s1, const SmartPtr<T>& s2) { 00145 return s1.sameObject(s2); 00146 } 00147 00148 template <class T> bool operator!=(const SmartPtr<T>& s1, const SmartPtr<T>& s2) { 00149 return !s1.sameObject(s2); 00150 } 00151 00152 }; 00153 00154 #else 00155 #error smartptr.h included twice 00156 #endif // SMARTPTR_H
Contact me in case of errors or questions. This documentation is powered by ![]() |
(C) 2000-2002 ![]() |