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