// // This file contains another implementation of smart pointers. It is // different from the implementation found in smartptr.h because the // object itself deletes itself when its reference count hits 0. This // is similar to the way COM objects are written. // #ifndef _SMARTP2_H_ #define _SMARTP2_H_ #include // // A reference counting implementation // class CRefCount2 { protected: LONG m_cRefs; public: CRefCount2() { m_cRefs = 1; } virtual ~CRefCount2() { } LONG AddRef() { return InterlockedIncrement(&m_cRefs); } void Release() { LONG r = InterlockedDecrement(&m_cRefs); _ASSERT(r >= 0); if (r == 0) delete this; } }; template class CRefPtr2; // // This is a type of pointer which can be returned by functions. The only // valid operation on it is to copy it to a CRefPtr2 pointer. It // tells the CRefPtr2 not to do an AddRef. // template class CRefPtr2HasRef { protected: Type *m_p; CRefPtr2HasRef& operator=(const CRefPtr2HasRef& rhs) { _ASSERT(FALSE); return *this; } BOOL operator==(CRefPtr2&rhs) { _ASSERT(FALSE); return m_p == rhs.m_p; } BOOL operator!=(CRefPtr2&rhs) { _ASSERT(FALSE); return m_p != rhs.m_p; } public: // // Do nothing protected constructor ! // CRefPtr2HasRef() : m_p( 0 ) { } CRefPtr2HasRef(const Type *p ) : m_p( (Type*)p ) { if (m_p) m_p->AddRef(); } ~CRefPtr2HasRef() { // this pointer always needs to be copied to a CRefPtr2, which // should set m_p to NULL _ASSERT(m_p == NULL); } friend class CRefPtr2; }; template class CHasRef : public CRefPtr2HasRef { public : CHasRef( const Type* p = 0 ) { m_p = (Type*)p ; if( fAddRef ) { if( m_p ) m_p->AddRef() ; } } } ; template< class Type > class CRefPtr2 { private: Type* m_p ; public : CRefPtr2(const CRefPtr2& ref) { m_p = ref.m_p; if (m_p) m_p->AddRef(); } // copy from an intermediate pointer -- we don't need to do an addref CRefPtr2(CRefPtr2HasRef &ref) { m_p = ref.m_p; ref.m_p = NULL; } CRefPtr2(const Type *p = 0) { m_p = (Type *) p; if (m_p) m_p->AddRef(); } ~CRefPtr2() { if (m_p) m_p->Release(); } CRefPtr2& operator=(const CRefPtr2& rhs) { if (m_p != rhs.m_p) { Type *pTemp = m_p; m_p = rhs.m_p; if (m_p) m_p->AddRef(); if (pTemp) pTemp->Release(); } return *this; } // copy from an intermediate pointer -- we don't need to do an addref CRefPtr2& operator=(CRefPtr2HasRef& rhs) { Type *pTemp = m_p; m_p = rhs.m_p; if (pTemp) pTemp->Release(); rhs.m_p = NULL; return *this; } CRefPtr2& operator=(const Type *rhs) { if (m_p != rhs) { Type *pTemp = m_p; m_p = (Type *) rhs; if (m_p) m_p->AddRef(); if (pTemp) pTemp->Release(); } return *this; } BOOL operator==(CRefPtr2&rhs) { return m_p == rhs.m_p; } BOOL operator!=(CRefPtr2&rhs) { return m_p != rhs.m_p; } BOOL operator==(Type *p) { return m_p == p; } BOOL operator!=(Type *p) { return m_p != p; } Type *operator->() const { return m_p ; } operator Type*() const { return m_p ; } BOOL operator!() const { return !m_p ; } }; #endif