Heidelberg Educational Numerics Library Version 0.24 (from 9 September 2011)
|
00001 // -*- tab-width: 4; indent-tabs-mode: nil -*- 00002 #ifndef HDNUM_COUNTINGPTR_HH 00003 #define HDNUM_COUNTINGPTR_HH 00004 00005 #include <iostream> 00006 00013 namespace hdnum { 00014 00021 class NondeletingMemoryManagementPolicy 00022 { 00023 public: 00024 template<typename T> 00025 static void delete_action (T* p) 00026 {} 00027 }; 00028 00035 class DeletingMemoryManagementPolicy 00036 { 00037 public: 00038 template<typename T> 00039 static void delete_action (T* p) 00040 { 00041 if (p->reference_counter_zero()) 00042 delete p; 00043 } 00044 }; 00045 00046 template<typename T, typename P=DeletingMemoryManagementPolicy> 00069 class CP 00070 { 00071 T* p; 00072 00073 public: 00075 CP () 00076 { 00077 p = 0; 00078 } 00079 00081 explicit CP (T* p_) 00082 { 00083 p = p_; 00084 if (p!=0) 00085 p->reference_counter_increment(); 00086 } 00087 00089 CP (const CP<T>& cp) 00090 { 00091 p = cp.p; 00092 if (p!=0) 00093 p->reference_counter_increment(); 00094 } 00095 00097 ~CP () 00098 { 00099 if (p!=0) 00100 { 00101 p->reference_counter_decrement(); 00102 P::delete_action(p); 00103 } 00104 } 00105 00107 CP<T>& operator= (T* p_) 00108 { 00109 if (p!=p_) 00110 { 00111 if (p!=0) 00112 p->reference_counter_decrement(); 00113 p = p_; 00114 if (p!=0) 00115 p->reference_counter_increment(); 00116 } 00117 return *this; 00118 } 00119 00121 CP<T>& operator= (const CP<T>& cp) 00122 { 00123 if (p!=cp.p) 00124 { 00125 if (p!=0) 00126 p->reference_counter_decrement(); 00127 p = cp.p; 00128 if (p!=0) 00129 p->reference_counter_increment(); 00130 } 00131 return *this; 00132 } 00133 00135 T* operator-> () const 00136 { 00137 return p; 00138 } 00139 00141 T& operator* () const 00142 { 00143 return *p; 00144 } 00145 00147 bool operator== (const CP<T>& cp) const 00148 { 00149 return p==cp.p; 00150 } 00151 00153 bool operator!= (const CP<T>& cp) const 00154 { 00155 return p!=cp.p; 00156 } 00157 00158 }; 00159 00160 class CountableException 00161 { 00162 int counter; 00163 public: 00164 CountableException (int i) : counter(i) {} 00165 int get_counter () const 00166 { 00167 return counter; 00168 } 00169 }; 00170 00176 class Countable 00177 { 00178 mutable int counter; 00179 00180 public: 00181 00183 Countable () : counter(0) 00184 { 00185 } 00186 00188 Countable (const Countable& ) 00189 { 00190 counter = 0; 00191 } 00192 00194 Countable& operator= (const Countable& ) 00195 { 00196 return *this; 00197 } 00198 00200 void reference_counter_increment () const 00201 { 00202 counter++; 00203 } 00204 00206 void reference_counter_decrement () const 00207 { 00208 counter--; 00209 } 00210 00212 bool reference_counter_zero () const 00213 { 00214 return counter==0; 00215 } 00216 00218 int get_reference_counter () const 00219 { 00220 return counter; 00221 } 00222 00227 ~Countable () 00228 { 00229 if (counter!=0) 00230 { 00231 std::cout << counter << " counting pointer(s) point to object at " 00232 << this << " while it is deleted" << std::endl; 00233 throw CountableException(counter); 00234 } 00235 } 00236 }; 00237 00238 } // namespace hdnum 00239 00240 #endif