template<typename T>
class CAutoPtr
{
typedef CAutoPtr<T> TSelf;
public:
CAutoPtr() :
m_pT(NULL)
{
}
explicit CAutoPtr(T* pT) :
m_pT(pT)
{
dupOrEval(pT);
}
CAutoPtr(const TSelf & other) :
m_pT(TSelf::duplicate(other.get()))
{
}
TSelf& operator =(const TSelf& other)
{
if (this != &other)
{
reset(other.get());
}
return *this;
}
TSelf& operator =(T* pT)
{
if (pT == m_pT)
{
return *this;
}
free();
dupOrEval(pT);
return *this;
}
~CAutoPtr()
{
free();
}
operator const T*() const
{
return m_pT;
}
operator T*()
{
return m_pT;
}
T& operator *()
{
return *m_pT;
}
const T& operator *() const
{
return *m_pT;
}
T* operator ->()
{
assert(m_pT);
return m_pT;
}
const T* operator ->() const
{
assert(m_pT);
return m_pT;
}
const T* get() const
{
return m_pT;
}
T* get()
{
return m_pT;
}
private:
void free()
{
if (m_pT)
{
m_pT->releaseRef();
}
m_pT = NULL;
}
void reset(const T* pT)
{
free();
m_pT = TSelf::duplicate(pT);
}
void dupOrEval(T* pT)
{
if (pT)
{
if (pT->isHasPassToAutoPtr())
{
m_pT = TSelf::duplicate(pT);
}
else
{
// come from a pointer that allocated by new, the default ref count is 1
// not call addRef() func
m_pT = pT;
m_pT->setHasPassToAutoPtr();
}
}
else
{
m_pT = NULL;
}
}
static T* duplicate(const T* pT)
{
T* t_pT = const_cast<T*> (pT);
if (t_pT != NULL)
{
t_pT->addRef();
}
return t_pT;
}
private:
T * m_pT;
};