SOUI的智能指针赏析
之前自己设计Ref类型遇到new出来的地址,和Ref的this指针一致的情况,soui的这套做法一定程度避免了
如果有普通的单根继承直接使用: public TObjRefImpl<IRef>
如果是多根继承可以指定析构类型 : public TObjRefImpl2<TDeleteType>
但是多重继承两个Ref类还是没有解决,原则上应该劲量不再非接口是上使用多重继承
1 template< class T>
2 class TObjRefImpl : public T
3 {
4 public:
5 TObjRefImpl():m_cRef(1)
6 {
7 }
8
9 virtual ~TObjRefImpl(){
10 }
11
12 // !添加引用
13 /* !
14 */
15 virtual long AddRef()
16 {
17 return InterlockedIncrement(&m_cRef);
18 }
19
20 // !释放引用
21 /* !
22 */
23 virtual long Release()
24 {
25 long lRet = InterlockedDecrement(&m_cRef);
26 if(lRet==0)
27 {
28 OnFinalRelease();
29 }
30 return lRet;
31 }
32
33 // !释放对象
34 /* !
35 */
36 virtual void OnFinalRelease()
37 {
38 delete this;
39 }
40 protected:
41 volatile LONG m_cRef;
42 };
43
44 template< class T, class T2>
45 class TObjRefImpl2 : public TObjRefImpl<T>
46 {
47 public:
48 virtual void OnFinalRelease()
49 {
50 delete static_cast<T2*>( this);
51 }
52 };
53
54 // CAutoRefPtr provides the basis for all other smart pointers
55 template < class T>
56 class CAutoRefPtr
57 {
58 public:
59 CAutoRefPtr() throw()
60 {
61 p = NULL;
62 }
63 CAutoRefPtr(_In_ int nNull) throw()
64 {
65 ( void)nNull;
66 p = NULL;
67 }
68 CAutoRefPtr(_In_opt_ T* lp) throw()
69 {
70 p = lp;
71 if (p != NULL)
72 {
73 p->AddRef();
74 }
75 }
76
77 CAutoRefPtr( const CAutoRefPtr & src) throw()
78 {
79 p=src.p;
80 if(p)
81 {
82 p->AddRef();
83 }
84 }
85
86 ~CAutoRefPtr() throw()
87 {
88 if (p)
89 {
90 p->Release();
91 }
92 }
93
94 T* operator->() const throw()
95 {
96 return p;
97 }
98
99 operator T*() const throw()
100 {
101 return p;
102 }
103 T& operator*() const
104 {
105 return *p;
106 }
107 // The assert on operator& usually indicates a bug. If this is really
108 // what is needed, however, take the address of the p member explicitly.
109 T** operator&() throw()
110 {
111 SASSERT(p==NULL);
112 return &p;
113 }
114 bool operator!() const throw()
115 {
116 return (p == NULL);
117 }
118 bool operator<(_In_opt_ T* pT) const throw()
119 {
120 return p < pT;
121 }
122 bool operator!=(_In_opt_ T* pT) const
123 {
124 return ! operator==(pT);
125 }
126 bool operator==(_In_opt_ T* pT) const throw()
127 {
128 return p == pT;
129 }
130
131 T* operator=(_In_opt_ T* lp) throw()
132 {
133 if(* this!=lp)
134 {
135 if(p)
136 {
137 p->Release();
138 }
139 p=lp;
140 if(p)
141 {
142 p->AddRef();
143 }
144 }
145 return * this;
146 }
147
148 T* operator=(_In_ const CAutoRefPtr<T>& lp) throw()
149 {
150 if(* this!=lp)
151 {
152 if(p)
153 {
154 p->Release();
155 }
156 p=lp;
157 if(p)
158 {
159 p->AddRef();
160 }
161 }
162 return * this;
163 }
164
165 // Release the interface and set to NULL
166 void Release() throw()
167 {
168 T* pTemp = p;
169 if (pTemp)
170 {
171 p = NULL;
172 pTemp->Release();
173 }
174 }
175
176 // Attach to an existing interface (does not AddRef)
177 void Attach(_In_opt_ T* p2) throw()
178 {
179 if (p)
180 {
181 p->Release();
182 }
183 p = p2;
184 }
185 // Detach the interface (does not Release)
186 T* Detach() throw()
187 {
188 T* pt = p;
189 p = NULL;
190 return pt;
191 }
192 HRESULT CopyTo(_Deref_out_opt_ T** ppT) throw()
193 {
194 if (ppT == NULL)
195 return E_POINTER;
196 *ppT = p;
197 if (p)
198 {
199 p->AddRef();
200 }
201 return S_OK;
202 }
203
204 protected:
205 T* p;
206 };
如果有普通的单根继承直接使用: public TObjRefImpl<IRef>
如果是多根继承可以指定析构类型 : public TObjRefImpl2<TDeleteType>
但是多重继承两个Ref类还是没有解决,原则上应该劲量不再非接口是上使用多重继承
1 template< class T>
2 class TObjRefImpl : public T
3 {
4 public:
5 TObjRefImpl():m_cRef(1)
6 {
7 }
8
9 virtual ~TObjRefImpl(){
10 }
11
12 // !添加引用
13 /* !
14 */
15 virtual long AddRef()
16 {
17 return InterlockedIncrement(&m_cRef);
18 }
19
20 // !释放引用
21 /* !
22 */
23 virtual long Release()
24 {
25 long lRet = InterlockedDecrement(&m_cRef);
26 if(lRet==0)
27 {
28 OnFinalRelease();
29 }
30 return lRet;
31 }
32
33 // !释放对象
34 /* !
35 */
36 virtual void OnFinalRelease()
37 {
38 delete this;
39 }
40 protected:
41 volatile LONG m_cRef;
42 };
43
44 template< class T, class T2>
45 class TObjRefImpl2 : public TObjRefImpl<T>
46 {
47 public:
48 virtual void OnFinalRelease()
49 {
50 delete static_cast<T2*>( this);
51 }
52 };
53
54 // CAutoRefPtr provides the basis for all other smart pointers
55 template < class T>
56 class CAutoRefPtr
57 {
58 public:
59 CAutoRefPtr() throw()
60 {
61 p = NULL;
62 }
63 CAutoRefPtr(_In_ int nNull) throw()
64 {
65 ( void)nNull;
66 p = NULL;
67 }
68 CAutoRefPtr(_In_opt_ T* lp) throw()
69 {
70 p = lp;
71 if (p != NULL)
72 {
73 p->AddRef();
74 }
75 }
76
77 CAutoRefPtr( const CAutoRefPtr & src) throw()
78 {
79 p=src.p;
80 if(p)
81 {
82 p->AddRef();
83 }
84 }
85
86 ~CAutoRefPtr() throw()
87 {
88 if (p)
89 {
90 p->Release();
91 }
92 }
93
94 T* operator->() const throw()
95 {
96 return p;
97 }
98
99 operator T*() const throw()
100 {
101 return p;
102 }
103 T& operator*() const
104 {
105 return *p;
106 }
107 // The assert on operator& usually indicates a bug. If this is really
108 // what is needed, however, take the address of the p member explicitly.
109 T** operator&() throw()
110 {
111 SASSERT(p==NULL);
112 return &p;
113 }
114 bool operator!() const throw()
115 {
116 return (p == NULL);
117 }
118 bool operator<(_In_opt_ T* pT) const throw()
119 {
120 return p < pT;
121 }
122 bool operator!=(_In_opt_ T* pT) const
123 {
124 return ! operator==(pT);
125 }
126 bool operator==(_In_opt_ T* pT) const throw()
127 {
128 return p == pT;
129 }
130
131 T* operator=(_In_opt_ T* lp) throw()
132 {
133 if(* this!=lp)
134 {
135 if(p)
136 {
137 p->Release();
138 }
139 p=lp;
140 if(p)
141 {
142 p->AddRef();
143 }
144 }
145 return * this;
146 }
147
148 T* operator=(_In_ const CAutoRefPtr<T>& lp) throw()
149 {
150 if(* this!=lp)
151 {
152 if(p)
153 {
154 p->Release();
155 }
156 p=lp;
157 if(p)
158 {
159 p->AddRef();
160 }
161 }
162 return * this;
163 }
164
165 // Release the interface and set to NULL
166 void Release() throw()
167 {
168 T* pTemp = p;
169 if (pTemp)
170 {
171 p = NULL;
172 pTemp->Release();
173 }
174 }
175
176 // Attach to an existing interface (does not AddRef)
177 void Attach(_In_opt_ T* p2) throw()
178 {
179 if (p)
180 {
181 p->Release();
182 }
183 p = p2;
184 }
185 // Detach the interface (does not Release)
186 T* Detach() throw()
187 {
188 T* pt = p;
189 p = NULL;
190 return pt;
191 }
192 HRESULT CopyTo(_Deref_out_opt_ T** ppT) throw()
193 {
194 if (ppT == NULL)
195 return E_POINTER;
196 *ppT = p;
197 if (p)
198 {
199 p->AddRef();
200 }
201 return S_OK;
202 }
203
204 protected:
205 T* p;
206 };
struct IObjRef
{
virtual long AddRef() = 0;
virtual long Release() = 0;
virtual void OnFinalRelease() =0;
};
{
virtual long AddRef() = 0;
virtual long Release() = 0;
virtual void OnFinalRelease() =0;
};