You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
223 lines
2.8 KiB
223 lines
2.8 KiB
//IObjRef的实现类
|
|
#pragma once
|
|
|
|
#ifndef SASSERT
|
|
#include <assert.h>
|
|
#define SASSERT(x) assert(x);
|
|
#endif
|
|
|
|
namespace SOUI
|
|
{
|
|
|
|
template<class T>
|
|
class TObjRefImpl : public T
|
|
{
|
|
public:
|
|
TObjRefImpl():m_cRef(1)
|
|
{
|
|
}
|
|
|
|
virtual ~TObjRefImpl(){
|
|
}
|
|
|
|
//!添加引用
|
|
/*!
|
|
*/
|
|
virtual long AddRef()
|
|
{
|
|
return InterlockedIncrement(&m_cRef);
|
|
}
|
|
|
|
//!释放引用
|
|
/*!
|
|
*/
|
|
virtual long Release()
|
|
{
|
|
long lRet = InterlockedDecrement(&m_cRef);
|
|
if(lRet==0)
|
|
{
|
|
OnFinalRelease();
|
|
}
|
|
return lRet;
|
|
}
|
|
|
|
//!释放对象
|
|
/*!
|
|
*/
|
|
virtual void OnFinalRelease()
|
|
{
|
|
delete this;
|
|
}
|
|
protected:
|
|
volatile LONG m_cRef;
|
|
};
|
|
|
|
template<class T,class T2>
|
|
class TObjRefImpl2 : public TObjRefImpl<T>
|
|
{
|
|
public:
|
|
virtual void OnFinalRelease()
|
|
{
|
|
delete static_cast<T2*>(this);
|
|
}
|
|
};
|
|
|
|
//SAutoRefPtr provides the basis for all other smart pointers
|
|
template <class T>
|
|
class SAutoRefPtr
|
|
{
|
|
public:
|
|
SAutoRefPtr() throw()
|
|
{
|
|
p = NULL;
|
|
}
|
|
SAutoRefPtr(int nNull) throw()
|
|
{
|
|
(void)nNull;
|
|
p = NULL;
|
|
}
|
|
SAutoRefPtr(T* lp) throw()
|
|
{
|
|
p = lp;
|
|
if (p != NULL)
|
|
{
|
|
p->AddRef();
|
|
}
|
|
}
|
|
|
|
SAutoRefPtr(const SAutoRefPtr & src) throw()
|
|
{
|
|
p=src.p;
|
|
if(p)
|
|
{
|
|
p->AddRef();
|
|
}
|
|
}
|
|
|
|
~SAutoRefPtr() throw()
|
|
{
|
|
if (p)
|
|
{
|
|
p->Release();
|
|
}
|
|
}
|
|
|
|
T* operator->() const throw()
|
|
{
|
|
return p;
|
|
}
|
|
|
|
operator T*() const throw()
|
|
{
|
|
return p;
|
|
}
|
|
T& operator*() const
|
|
{
|
|
return *p;
|
|
}
|
|
//The assert on operator& usually indicates a bug. If this is really
|
|
//what is needed, however, take the address of the p member explicitly.
|
|
T** operator&() throw()
|
|
{
|
|
SASSERT(p==NULL);
|
|
return &p;
|
|
}
|
|
bool operator!() const throw()
|
|
{
|
|
return (p == NULL);
|
|
}
|
|
bool operator<(T* pT) const throw()
|
|
{
|
|
return p < pT;
|
|
}
|
|
bool operator!=(T* pT) const
|
|
{
|
|
return !operator==(pT);
|
|
}
|
|
bool operator==(T* pT) const throw()
|
|
{
|
|
return p == pT;
|
|
}
|
|
|
|
T* operator=(T* lp) throw()
|
|
{
|
|
if(*this!=lp)
|
|
{
|
|
if(p)
|
|
{
|
|
p->Release();
|
|
}
|
|
p=lp;
|
|
if(p)
|
|
{
|
|
p->AddRef();
|
|
}
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
T* operator=(const SAutoRefPtr<T>& lp) throw()
|
|
{
|
|
if(*this!=lp)
|
|
{
|
|
if(p)
|
|
{
|
|
p->Release();
|
|
}
|
|
p=lp;
|
|
if(p)
|
|
{
|
|
p->AddRef();
|
|
}
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
// Release the interface and set to NULL
|
|
void Release() throw()
|
|
{
|
|
T* pTemp = p;
|
|
if (pTemp)
|
|
{
|
|
p = NULL;
|
|
pTemp->Release();
|
|
}
|
|
}
|
|
|
|
// Attach to an existing interface (does not AddRef)
|
|
void Attach(T* p2) throw()
|
|
{
|
|
if (p)
|
|
{
|
|
p->Release();
|
|
}
|
|
p = p2;
|
|
}
|
|
// Detach the interface (does not Release)
|
|
T* Detach() throw()
|
|
{
|
|
T* pt = p;
|
|
p = NULL;
|
|
return pt;
|
|
}
|
|
HRESULT CopyTo(T** ppT) throw()
|
|
{
|
|
if (ppT == NULL)
|
|
return E_POINTER;
|
|
*ppT = p;
|
|
if (p)
|
|
{
|
|
p->AddRef();
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
protected:
|
|
T* p;
|
|
};
|
|
|
|
|
|
|
|
#define CAutoRefPtr SAutoRefPtr //for compatible
|
|
|
|
}//end of namespace SOUI
|
|
|