#pragma once
template <typename T>
class PtrData
{
friend class CSmartPtr<T>;
public:
explicit PtrData( const T* pT):p_(pT) { count_ = 1; }
~PtrData() { delete p_; count_ = 0; }
void operator ++ () { ++count_; }
void operator -- () { --count_; if (count_ == 0) { delete this; } }
T* operator -> () const { return p_; }
T& operator * () const { return *p_; }
bool operator == (T* pt) const { return p_ == pt; }
T* get () const { return p_; }
unsigned int use_count() const { return count_; }
private:
T* p_;
unsigned int count_;
};
template <typename T>
class CSmartPtr
{
public:
CSmartPtr():ptr_(NULL){}
explicit CSmartPtr(T* pT):ptr_(NULL)
{
ptr_ = new PtrData<T>(pT);
}
CSmartPtr(const CSmartPtr<T>& rt)
{
ptr_ = rt.get_ptr();
if (ptr_ != NULL)
{
++(*ptr_);
}
}
~CSmartPtr()
{
if (ptr_ != NULL)
{
--(*ptr_);
}
}
CSmartPtr<T>& operator = (const CSmartPtr<T>& rt)
{
if (ptr_ != NULL)
{
--(*ptr_);
}
ptr_ = rt.get_ptr();
++(*ptr_);
return *this;
}
T* operator -> ()
{
return ptr_-> operator ->();
}
T& operator * ()
{
return ptr_->operator *();
}
bool operator == (const CSmartPtr<T>& rt) const
{
return ptr_ == rt.get_ptr();
}
bool operator == (T* pt) const
{
if (pt == NULL)
{
return ptr_ == NULL;
}
return *ptr_ == pt;
}
T* get() const
{
if (ptr_ == NULL)
{
return NULL;
}
return ptr_->get();
}
void release()
{
if (ptr_ != NULL)
{
--(*ptr_);
ptr_ = NULL;
}
}
void reset(T* pt)
{
if (ptr_ != NULL)
{
--(*ptr_);
ptr_ = NULL;
}
ptr_ = new CSmartPtr<T>(pt);
}
inline bool IsNull() const {return ptr_ == NULL;}
private:
CSmartPtr<T>* get_ptr() const {return ptr_;}
PtrData<T>* ptr_;
};