用模板实现引用计数#ifndef T_NO_ANSI_CASTS # define T_REINTERPRET_CAST(type,pointer) reinterpret_cas
用模板实现引用计数
#ifndef T_NO_ANSI_CASTS # define T_REINTERPRET_CAST(type,pointer) reinterpret_cast< type >(pointer)# define T_STATIC_CAST(type,pointer) static_cast< type >(pointer)# define T_CONST_CAST(type,pointer) const_cast< type >(pointer)#else# define RW_REINTERPRET_CAST(type,pointer) (type)pointer# define RW_STATIC_CAST(type,pointer) (type)pointer# define RW_CONST_CAST(type,pointer) (type)pointer#endif /* T_NO_ANSI_CASTS */class CReference {public: CReference(){} virtual ~CReference() {} void addReference() { refCount_ ++; } int removeReference() { return refCount_ --; } int references() const { return refCount_; }private: volatile int refCount_; //unimplemented: // If you ever implement these, use rwAtomicExchange to copy the classes CReference(const CReference&); CReference& operator=(const CReference&);};template<class T> class CCountedRef{public: CCountedRef() { impl_ = new T; } CCountedRef(T* impl) : impl_(impl) { if(impl_) { T_STATIC_CAST(CReference*, impl_)->addReference(); } } CCountedRef(const CCountedRef<T>& ref) :impl_(ref.impl_) // Always assign, even if NULL { if(ref.impl_) { //T_STATIC_CAST(CReference*, ref.impl_)->addReference(); } } ~CCountedRef() { detach(); } CCountedRef<T>& operator=(const CCountedRef<T>& rhs) { if(rhs.impl_) { T_STATIC_CAST(CReference*, rhs.impl_)->addReference(); } detach(); impl_ = rhs.impl_; return *this; } CCountedRef<T>& operator=(T* impl) { if(impl) { T_STATIC_CAST(CReference*, impl)->addReference(); } detach(); impl_ = impl; return *this; } operator T*() const { return impl_; } T* operator->() const { //assert(impl_); return impl_; } T& operator*() const { //assert(impl_); return *impl_; } bool operator==(const CCountedRef<T>& rhs) const { return (impl_ && (impl_ == rhs.impl_)); } bool operator!=(const CCountedRef<T>& rhs) const { return !(impl_ && (impl_ == rhs.impl_)); }protected: void detach() { if(impl_ && T_STATIC_CAST(CReference*, impl_)->removeReference() < 1) { //If the following line fails when: // (1) It was already deleted? // (2) The object was created on the stack delete T_STATIC_CAST(CReference*, impl_); impl_ = NULL; } } T* impl_;};template<class T> class CMTCountedRef{ typedef ACE_Thread_Mutex CMTCRefMutexType;public: // We didn't assign NULL for initialization to avoid threading problems CMTCountedRef(T* impl) { //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex()); ACE_Guard<ACE_Thread_Mutex> guard(m_mtx); if(impl) { T_STATIC_CAST(CReference*, impl)->addReference(); } impl_ = impl; } // We didn't assign NULL for initialization to avoid threading problems CMTCountedRef(const CMTCountedRef<T>& ref) { //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex()); ACE_Guard<ACE_Thread_Mutex>guard(m_mtx); if(ref.impl_) { T_STATIC_CAST(CReference*, ref.impl_)->addReference(); } impl_ = ref.impl_; } virtual ~CMTCountedRef() { //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex()); ACE_Guard<ACE_Thread_Mutex> guard(m_mtx); detach(); } CMTCountedRef<T>& operator=(const CMTCountedRef<T>& rhs) { //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex()); ACE_Guard<ACE_Thread_Mutex> guard(m_mtx); if(rhs.impl_) RWDBSTATIC_CAST(CReference*, rhs.impl_)->addReference(); detach(); impl_ = rhs.impl_; return *this; } CMTCountedRef<T>& operator=(T* impl) { //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex()); ACE_Guard<ACE_Thread_Mutex> guard(m_mtx); if(impl) RWDBSTATIC_CAST(CReference*, impl)->addReference(); detach(); impl_ = impl; return *this; } operator T*() const { //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex()); ACE_Guard<ACE_Thread_Mutex> guard(m_mtx); return impl_; } T* operator->() const { //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex()); ACE_Guard<ACE_Thread_Mutex> guard(m_mtx); //assert(impl_); return impl_; } T& operator*() const { //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex()); ACE_Guard<ACE_Thread_Mutex> guard(m_mtx); //assert(impl_); return *impl_; } bool operator==(const CMTCountedRef<T>& rhs) const { //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex()); ACE_Guard<ACE_Thread_Mutex> guard(m_mtx); return ( impl_ && ( impl_ == rhs.impl_ ) ); } bool operator!=(const CMTCountedRef<T>& rhs) const { //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex()); ACE_Guard<ACE_Thread_Mutex> guard(m_mtx); return ! ( impl_ && ( impl_ == rhs.impl_ ) ); }protected: void detach() { //No need for the MT Guard, because we are already heavily // guarded against concurrent access. if(impl_ && T_STATIC_CAST(CReference*, impl_)->removeReference() < 1) { //If the following line fails then: // (1) It was already deleted? // (2) The object was created on the stack //delete RWDBREINTERPRET_CAST(RWDBReference*, impl_); delete REINTERPRET_CAST(RWDBReference*, impl_); impl_ = NULL; } } CMTCRefMutexType m_mtx;private: T* impl_;};class TTestImpl : public CReference{public: TTestImpl() { m_buffer = new char[1024]; memset(m_buffer, 0x0, 1024); } ~TTestImpl() { if (NULL != m_buffer) { delete m_buffer; m_buffer = NULL; } } void Func() { printf("Hello Tiky....."); }private: char *m_buffer;};class TTest{public: TTest(){} ~TTest(){} void Func() { m_impl->Func(); }private: CCountedRef<TTestImpl> m_impl;};int main(int argc, char *argv[]){ TTest myTest; { TTest myTest1 = myTest; myTest1.Func(); } myTest.Func(); return 0;}