#pragma once #include #include template class CSmartPointer { public: CSmartPointer():m_pPoint(NULL),m_pnReference(NULL){} CSmartPointer(T *pPoint) :m_pPoint(pPoint), m_pnReference(NULL){} CSmartPointer(const CSmartPointer &Point) :m_pPoint(Point.m_pPoint),m_pnReference(Point.m_pnReference) { if(m_pnReference) InterlockedIncrement(m_pnReference); } ~CSmartPointer() { Clear(); } CSmartPointer &operator=(T *pPoint) { if(pPoint!=m_pPoint) { Clear(); m_pPoint=pPoint; } return *this; } CSmartPointer &operator =(const CSmartPointer &Point) { if(Point.m_pPoint!=m_pPoint) { Clear(); m_pPoint=Point.m_pPoint; m_pnReference=Point.m_pnReference; if(m_pnReference) InterlockedIncrement(m_pnReference); } return *this; } bool operator ==(T *pPoint)const { return m_pPoint==pPoint; } bool operator ==(const CSmartPointer &Point)const { return m_pPoint==Point.m_pPoint; } bool operator !=(T *pPoint)const { return m_pPoint!=pPoint; } bool operator !=(const CSmartPointer &Point)const { return m_pPoint!=Point.m_pPoint; } void Attach(T *pPoint) { Attach(pPoint, NULL); } void Attach(T *pPoint,LONG *pnReference) { if(m_pPoint!=pPoint) { Clear(); m_pPoint=pPoint; m_pnReference=pnReference; if(pnReference!=NULL && *pnReference>0) InterlockedIncrement(m_pnReference); else m_pnReference = new LONG(1); } } T *Detach() { if(m_pnReference) { if (*m_pnReference != 1) { assert(false); return NULL; } else { delete m_pnReference; m_pnReference=NULL; } } T *pRet=m_pPoint; m_pPoint=NULL; return pRet; } void AddRef() { if (m_pnReference != NULL && *m_pnReference > 0) InterlockedIncrement(m_pnReference); } void SubRef() { if (m_pnReference) { LONG nRef = InterlockedDecrement(m_pnReference); if (nRef == 0) { delete m_pPoint; delete m_pnReference; } m_pnReference = NULL; } } void Clear() { if(m_pnReference) { LONG nRef=InterlockedDecrement(m_pnReference); if(nRef==0) { delete m_pPoint; delete m_pnReference; } m_pnReference=NULL; } m_pPoint=NULL; } T *operator ->() const { return m_pPoint; } /*operator T*() const { return m_pPoint; }*/ T* GetRawPointer() const { return m_pPoint; } #if 1 template CSmartPointer

ConvertCase() { CSmartPointer

pRet; try { if (m_pnReference != NULL) pRet.Attach(dynamic_cast

(m_pPoint),m_pnReference); else pRet = dynamic_cast

(m_pPoint); // if not managed originally, ret pointer should not be managed too!!! } catch(...) { return NULL; } return pRet; } #else template CSmartPointer

ConvertCase() // do this a little bit brute-force { CSmartPointer

pRet; P **pp = (P**)((char*)(&pRet) + (size_t)(&((CSmartPointer*)0)->m_pPoint)); *pp = dynamic_cast

(m_pPoint); LONG **pr = (LONG**)((char*)(&pRet) + (size_t)(&((CSmartPointer*)0)->m_pnReference)); *pr = m_pnReference; if(m_pnReference) InterlockedIncrement(m_pnReference); return pRet; } #endif private: T *m_pPoint; LONG *m_pnReference; };