00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef BAKERY_UTILITIES_SHAREDPTR_H
00020 #define BAKERY_UTILITIES_SHAREDPTR_H
00021
00022 #include <iostream>
00023
00024 namespace Bakery
00025 {
00026
00030 template< typename T_obj >
00031 class sharedptr
00032 {
00033 public:
00034 typedef size_t size_type;
00035
00037 sharedptr();
00038
00040 explicit sharedptr(T_obj* pobj);
00041
00043 sharedptr(const sharedptr& src);
00044
00046 sharedptr& operator=(const sharedptr& src);
00047
00048 virtual ~sharedptr();
00049
00052 inline T_obj& operator*();
00053
00056 inline const T_obj& operator*() const;
00057
00065 inline T_obj* operator->() const;
00066
00075 inline operator bool() const;
00076
00078 inline T_obj* obj();
00079
00081 inline const T_obj* obj() const;
00082
00083
00084 protected:
00085 inline void ref();
00086 inline void unref();
00087
00088 size_type* m_pRefCount;
00089 T_obj* m_pobj;
00090 };
00091
00092 template< typename T_obj>
00093 sharedptr<T_obj>::sharedptr()
00094 : m_pRefCount(0), m_pobj(0)
00095 {
00096
00097 }
00098
00099 template< typename T_obj>
00100 sharedptr<T_obj>::sharedptr(T_obj* pobj)
00101 : m_pRefCount(0), m_pobj(pobj)
00102 {
00103
00104 ref();
00105 }
00106
00107 template< typename T_obj>
00108 sharedptr<T_obj>::sharedptr(const sharedptr<T_obj>& src)
00109 : m_pRefCount(src.m_pRefCount), m_pobj(src.m_pobj)
00110 {
00111 ref();
00112 }
00113
00114 template< typename T_obj>
00115 sharedptr<T_obj>& sharedptr<T_obj>::operator=(const sharedptr<T_obj>& src)
00116 {
00117
00118 if(&src != this)
00119 {
00120
00121
00122 if(m_pobj)
00123 {
00124 unref();
00125 }
00126
00127
00128 m_pobj = src.m_pobj;
00129
00130 m_pRefCount = src.m_pRefCount;
00131 ref();
00132 }
00133
00134 return *this;
00135 }
00136
00137 template< typename T_obj>
00138 sharedptr<T_obj>::~sharedptr()
00139 {
00140 unref();
00141 }
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 template< typename T_obj>
00152 inline
00153 T_obj* sharedptr<T_obj>::obj()
00154 {
00155 return m_pobj;
00156 }
00157
00158 template< typename T_obj>
00159 inline
00160 const T_obj* sharedptr<T_obj>::obj() const
00161 {
00162 return m_pobj;
00163 }
00164
00165 template< typename T_obj>
00166 inline
00167 T_obj& sharedptr<T_obj>::operator*()
00168 {
00169 return *m_pobj;
00170 }
00171
00172 template< typename T_obj>
00173 inline
00174 const T_obj& sharedptr<T_obj>::operator*() const
00175 {
00176 return *m_pobj;
00177 }
00178
00179 template< typename T_obj>
00180 inline
00181 T_obj* sharedptr<T_obj>::operator->() const
00182 {
00183 return m_pobj;
00184 }
00185
00186 template <class T_obj>
00187 inline
00188 sharedptr<T_obj>::operator bool() const
00189 {
00190 return (m_pobj != 0);
00191 }
00192
00193
00194 template <class T_obj>
00195 inline
00196 void sharedptr<T_obj>::ref()
00197 {
00198 if(m_pobj)
00199 {
00200 if(m_pRefCount == 0)
00201 {
00202
00203
00204 m_pRefCount = new size_type();
00205 *m_pRefCount = 1;
00206 }
00207 else
00208 {
00209
00210 (*m_pRefCount)++;
00211 }
00212 }
00213 }
00214
00215 template <class T_obj>
00216 inline
00217 void sharedptr<T_obj>::unref()
00218 {
00219 if(m_pRefCount)
00220 {
00221
00222
00223 if( (*m_pRefCount) > 0 )
00224 (*m_pRefCount)--;
00225
00226
00227 if(*m_pRefCount == 0)
00228 {
00229 if(m_pobj)
00230 {
00231
00232
00233
00234 delete m_pobj;
00235 m_pobj = 0;
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 m_pobj = 0;
00246 }
00247
00248
00249 delete m_pRefCount;
00250 m_pRefCount = 0;
00251 }
00252 }
00253 else
00254 {
00255
00256 }
00257
00258 }
00259
00260
00261 }
00262
00263 #endif //BAKERY_UTILITIES_SHAREDPTR_H
00264