SharedPtr.h++
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __ccxx_SharedPtr_hxx
00024 #define __ccxx_SharedPtr_hxx
00025
00026 #include <commonc++/Common.h++>
00027 #include <commonc++/AtomicCounter.h++>
00028 #include <commonc++/NullPointerException.h++>
00029
00030 namespace ccxx {
00031
00038 template<class T> class SharedPtr
00039 {
00040 public:
00041
00043 SharedPtr(T *object = NULL)
00044 : _object(object), _refs(new AtomicCounter(1))
00045 { }
00046
00048 SharedPtr(const SharedPtr &other)
00049 : _object(other._object),
00050 _refs(other._refs)
00051 {
00052 ++(*_refs);
00053 }
00054
00056 ~SharedPtr()
00057 {
00058 _release();
00059 }
00060
00064 template<class U> SharedPtr<U> staticCast()
00065 { return SharedPtr<U>(*this, false); }
00066
00070 template<class U> SharedPtr<U> dynamicCast()
00071 { return SharedPtr<U>(*this); }
00072
00074 SharedPtr& operator=(const SharedPtr &other)
00075 {
00076 if(other._object == _object)
00077 return(*this);
00078
00079 _release();
00080 _object = other._object;
00081 _refs = other._refs;
00082 ++(*_refs);
00083 return(*this);
00084 }
00085
00087 SharedPtr& operator=(T *object)
00088 {
00089 if(_object != object)
00090 {
00091 _release();
00092 _object = object;
00093 _refs = new AtomicCounter(1);
00094 }
00095
00096 return(*this);
00097 }
00098
00100 T* operator->() throw()
00101 { return(_object); }
00102
00104 const T* operator->() const throw()
00105 { return(_object); }
00106
00111 T& operator*() throw(NullPointerException)
00112 {
00113 if(! _object)
00114 throw NullPointerException();
00115
00116 return(*_object);
00117 }
00118
00123 const T& operator*() const throw(NullPointerException)
00124 {
00125 if(! _object)
00126 throw NullPointerException();
00127 return(*_object);
00128 }
00129
00131 T* get() const
00132 { return(_object); }
00133
00135 bool operator!() const throw()
00136 { return(isNull()); }
00137
00139 operator const void *() const throw()
00140 { return(_object ? this : NULL); }
00141
00143 bool isNull() const throw()
00144 { return(_object == NULL); }
00145
00147 bool operator==(const SharedPtr &other) const
00148 { return(_object == other._object); }
00149
00151 bool operator!=(const SharedPtr &other) const
00152 { return(! operator==(other)); }
00153
00155 int getRefCount() const throw()
00156 { return(_object ? _refs->get() : 0); }
00157
00158 private:
00159
00160 template<class U> friend class SharedPtr;
00161
00162 template<typename U>
00163 explicit SharedPtr(const SharedPtr<U> &other)
00164 : _object(dynamic_cast<T *>(other._object))
00165 {
00166 if(_object)
00167 {
00168 _refs = other._refs;
00169 ++(*_refs);
00170 }
00171 else
00172 _refs = new AtomicCounter(1);
00173 }
00174
00175 template<typename U>
00176 SharedPtr(const SharedPtr<U> &other, bool tag)
00177 : _object(static_cast<T *>(other._object)),
00178 _refs(other._refs)
00179 {
00180 ++(*_refs);
00181 }
00182
00183 void _release()
00184 {
00185 if(--(*_refs) == 0)
00186 {
00187 delete _object;
00188 delete _refs;
00189 }
00190 }
00191
00192 T *_object;
00193 AtomicCounter *_refs;
00194 };
00195
00196 };
00197
00198 #endif // __ccxx_SharedPtr_hxx
00199
00200