00001 #ifndef IBRCOMMON_refcnt_ptr_h 00002 #define IBRCOMMON_refcnt_ptr_h 1 00003 00004 #include "ibrcommon/thread/Mutex.h" 00005 #include "ibrcommon/thread/MutexLock.h" 00006 00007 template <class T> class refcnt_ptr 00008 { 00009 protected: 00010 // a helper class that holds the pointer to the managed object 00011 // and its reference count 00012 class Holder 00013 { 00014 public: 00015 Holder( T* ptr) : ptr_(ptr), count_(1) {}; 00016 virtual ~Holder() { delete ptr_;}; 00017 00018 T* ptr_; 00019 unsigned count_; 00020 ibrcommon::Mutex lock; 00021 }; 00022 00023 Holder* h_; 00024 00025 private: 00026 void down() 00027 { 00028 try { 00029 ibrcommon::MutexLock l(h_->lock); 00030 if (--h_->count_ == 0) throw true; 00031 } catch (const bool&) { 00032 delete h_; 00033 } 00034 } 00035 00036 public: 00037 // ctor of refcnt_ptr (p must not be NULL) 00038 explicit refcnt_ptr(T* p) : h_(new Holder(p)) 00039 { 00040 } 00041 00042 // dtor of refcnt_ptr 00043 ~refcnt_ptr() 00044 { 00045 down(); 00046 } 00047 00048 // copy and assignment of refcnt_ptr 00049 refcnt_ptr (const refcnt_ptr<T>& right) : h_(right.h_) 00050 { 00051 ibrcommon::MutexLock l(h_->lock); 00052 ++h_->count_; 00053 } 00054 00055 refcnt_ptr<T>& operator= (const refcnt_ptr<T>& right) 00056 { 00057 ibrcommon::MutexLock l(right.h_->lock); 00058 ++right.h_->count_; 00059 00060 down(); 00061 00062 h_ = right.h_; 00063 00064 return *this; 00065 } 00066 00067 refcnt_ptr<T>& operator= (refcnt_ptr<T>& right) 00068 { 00069 ibrcommon::MutexLock l(right.h_->lock); 00070 ++right.h_->count_; 00071 00072 down(); 00073 00074 h_ = right.h_; 00075 00076 return *this; 00077 } 00078 00079 // access to the managed object 00080 T* operator-> () { return h_->ptr_; } 00081 T& operator* () { return *h_->ptr_; } 00082 T* getPointer() { return h_->ptr_; } 00083 00084 const T* operator-> () const { return h_->ptr_; } 00085 const T& operator* () const { return *h_->ptr_; } 00086 const T* getPointer() const { return h_->ptr_; } 00087 }; 00088 #endif
1.7.1