Voici un code de "smart pointer" que je viens de trouver. Il me parait simple et assez universel.
Détail amusant, un operator "virgule" est défini. C'est bien la première fois que je vois ça.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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(); }
};
Qu'en pensez-vous ?
Merci.