1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| template<class T>
class auto_counter
{
long f_cnt;
T *f_ptr;
long Keep() { return ++f_cnt; }
long Release() { return --f_cnt; }
auto_counter()
:f_cnt(1),f_ptr(0) {}
explicit auto_counter(T *ptr)
:f_cnt(1),f_ptr(ptr) {}
auto_counter(const auto_counter<T> & r)
:f_cnt(r.f_cnt),f_ptr(r.f_ptr) {}
auto_counter<T> & operator=(const auto_counter<T> & r)
{ f_cnt=r.f_cnt;f_ptr=r.f_ptr;return *this; }
public:
T *Get()
{ return f_ptr; }
static auto_counter<T> *Init(T *ptr)
{ return new auto_counter<T>(ptr); }
static void Done(auto_counter<T> *p)
{
if (p && p->Release()==0)
{
delete p->f_ptr;
delete p;
}
}
static void Copy(auto_counter<T> **dpp,auto_counter<T> *sp)
{
if (!sp)
{
if (*dpp) Done(*dpp),*dpp=0;
}
else if (!*dpp)
(*dpp=sp)->Keep();
else if ((*dpp)->f_ptr!=sp->f_ptr)
{
Done(*dpp);
(*dpp=sp)->Keep();
}
}
};
template<class T>
class smart_ptr
{
auto_counter<T> *f_ac;
public:
smart_ptr()
:f_ac(NULL) {}
explicit smart_ptr(T *ptr)
:f_ac(NULL) { f_ac=auto_counter<T>::Init(ptr); }
smart_ptr(const smart_ptr<T> & r)
:f_ac(NULL) { auto_counter<T>::Copy(&f_ac,r.f_ac); }
smart_ptr<T> & operator=(const smart_ptr<T> & r)
{ auto_counter<T>::Copy(&f_ac,r.f_ac); return *this; }
~smart_ptr()
{ auto_counter<T>::Done(f_ac); }
bool operator,(bool b) const
{ return f_ac!=0 && f_ac->Get()!=0 && bool(*f_ac->Get())==b; }
operator bool() const
{ return f_ac!=0 && f_ac->Get()!=0; }
T & operator*() const
{ return *f_ac->Get(); }
T *operator->() const
{ return f_ac->Get(); }
T *get() const
{ return f_ac->Get(); }
}; |
Partager