对于动态申请的内存,C++语言为我们提供了new和delete运算符, 而没有像java一样,提供一个完整的GC机制,因此对于我们申请的动态内存,我们需要时刻记得释放,且不能重复释放,释放后不能再去使用... 因此在使用时造成很多不便,且容易出现很多问题,一旦出问题就造成core dump,程序直接挂掉 , 这个时候,智能指针的优势就体现出来了,智能指针符合RAII原则,资源获取就是初始化,在对象析构时,将资源进行释放,对动态内存做到一个比较好的管理
unique_ptr 持有对对象的独有权—两个unique_ptr不能指向一个对象,不能进行复制操作只能进行移动操作
unique_ptr拥有所有auto_ptr的功能,且unique_ptr通过将复制构造和赋值操作符私有化,将对象的所有权独有,很好的将auto_ptr的安全问题给规避掉了,unique_ptr的其他特点包括:1.提供删除器释放对象,允许用户自定义删除器 2.添加了对象数组的偏特化实现,new[],delete[] 3.使用C++ 11的右值引用特性,实现所有权转移 std::move()
本次实现,将unique_ptr的基本接口进行了实现,基本包括了unique_ptr的功能 (编译平台:Linux centos 7.0 编译器:gcc 4.8.5 )
使用std::unique_ptr时,需要#include <memory>头文件,具体使用代码如下(文件名:test_ptr.cpp):
1 #include <memory>
2 #include <iostream>
3
4 using namespace std;
5
6 class Test
7 {
8 public:
9 Test()
10 {
11 cout << "construct.." << endl;
12 }
13
14 ~Test()
15 {
16 cout << "destruct.." << endl;
17 }
18 };
19
20 void test()
21 {
22
23 }
24
25 int main()
26 {
27 //auto_ptr
28 Test* p = new Test();
29 auto_ptr<Test> ap(p);
30
31 //unique_ptr
32 Test* p1 = new Test();
33 unique_ptr<Test> up(new Test());
34 unique_ptr<Test> up1(move(up));
35
36
37
38 //unique_ptr<Test> up2 = up;
39
40 unique_ptr<int> up3(new int(5));
41
42 return 0;
43 }
具体实现代码如下,没有对动态对象数组及std::move()进行实现,动态对象数组实现代码和这差不多,写个模板偏特化即可,至于std::move()则和成员函数release()类似,转移所有权(文件名:unique_ptr_implement.cpp):
1 #include <iostream>
2 #include <assert.h>
3
4 using namespace std;
5
6 #define PTR_ASSERT(x) assert(x)
7
8 template<class T>
9 struct defalute_deleter
10 {
11 void defalute_deleter_method()
12 {
13 cout << "deleter method..." << endl;
14 }
15 void operator()(T* ptr)
16 {
17 if(ptr != NULL)
18 {
19 cout << "default deleter....." << endl;
20 delete ptr;
21 ptr = NULL;
22 }
23 }
24 };
25
26 template<typename T, typename deleter = defalute_deleter<T> >
27 class unique_ptr
28 {
29 public:
30 explicit unique_ptr(T* ptr = NULL);
31
32 unique_ptr(T* ptr, deleter d);
33
34 ~unique_ptr();
35
36 T* get();
37
38 void reset(T* ptr = NULL);
39
40 deleter& getDeleter();
41
42 T* release();
43
44 public:
45 T& operator*();
46
47 T* operator->();
48
49 operator bool() const;
50
51 private:
52 unique_ptr(unique_ptr& up);
53
54 unique_ptr& operator = (unique_ptr& up);
55
56 private:
57 T* m_ptr;
58
59 deleter m_deleter;
60 };
61
62 template<typename T, typename deleter>
63 unique_ptr<T, deleter>::unique_ptr(T* ptr /* = NULL */, deleter d)
64 {
65 if(ptr != NULL)
66 {
67 m_ptr = ptr;
68 m_deleter = d;
69 }
70 }
71
72 template<typename T, typename deleter>
73 unique_ptr<T, deleter>::unique_ptr(T* ptr /* = NULL */)
74 {
75 if(ptr != NULL)
76 {
77 m_ptr = ptr;
78 }
79 }
80
81 template<typename T, typename deleter>
82 unique_ptr<T, deleter>::~unique_ptr()
83 {
84 if(m_ptr != NULL)
85 {
86 m_deleter(m_ptr);
87 m_ptr = NULL;
88 }
89 }
90
91 template<typename T, typename deleter>
92 T& unique_ptr<T, deleter>::operator*()
93 {
94 PTR_ASSERT(m_ptr != NULL);
95
96 return *m_ptr;
97 }
98
99 template<class T, class deleter>
100 T* unique_ptr<T, deleter>::operator->()
101 {
102 PTR_ASSERT(m_ptr != NULL);
103
104 return m_ptr;
105 }
106
107 template<typename T, typename deleter>
108 T* unique_ptr<T, deleter>::get()
109 {
110 return m_ptr;
111 }
112
113 template<typename T, typename deleter>
114 void unique_ptr<T, deleter>::reset(T* ptr)
115 {
116 T* old_ptr = m_ptr;
117 m_ptr = ptr;
118
119 if(old_ptr != NULL)
120 {
121 m_deleter(old_ptr);
122 old_ptr = NULL;
123 }
124 }
125
126 template<typename T, typename deleter>
127 deleter& unique_ptr<T, deleter>::getDeleter()
128 {
129 return m_deleter;
130 }
131
132 template<typename T, typename deleter>
133 T* unique_ptr<T, deleter>::release()
134 {
135 T* pTemp = m_ptr;
136 m_ptr = NULL;
137
138 return pTemp;
139 }
140
141 template<typename T, typename deleter>
142 unique_ptr<T, deleter>::operator bool() const
143 {
144 return m_ptr != NULL;
145 }
146
147
148 //Test class
149 class Test
150 {
151 public:
152 Test()
153 {
154 cout << "construct.." << endl;
155 }
156
157 ~Test()
158 {
159 cout << "destruct.." << endl;
160 }
161
162 void method()
163 {
164 cout << "welcome Test.." << endl;
165 }
166 };
167
168 //custom deleter
169 template <class T>
170 struct custom_deleter
171 {
172 void deleter_method()
173 {
174 cout << "custom deleter method..." << endl;
175 }
176
177 void operator()(T* ptr)
178 {
179 cout << "custom deleter... " << endl;
180 delete ptr;
181 ptr = NULL;
182 }
183 };
184
185
186 int main()
187 {
188 //default deleter
189 cout << "=======default deleter====interface test begin: ========== " << endl;
190 unique_ptr<Test> up(new Test());
191
192 cout << "operator ->: " << endl;
193 up->method();
194
195 cout << "operator *: " << endl;
196 (*up).method();
197
198 cout << "operator bool: " << endl;
199 if(up){ cout<< "obj is exit" << endl;}
200
201 cout << "get: " << endl;
202 up.get()->method();
203
204 cout << "getDeleter: " << endl;
205 defalute_deleter<Test> del = up.getDeleter();
206 del.defalute_deleter_method();
207
208 cout << "release: " << endl;
209 unique_ptr<Test> up1(up.release());
210
211 //if take this, will die
212 //(*up).method();
213
214 cout << "reset: " << endl;
215 up1.reset();
216
217 //Custom deleter
218 cout << "=======Custom deleter====interface test begin: ========== " << endl;
219 custom_deleter<Test> d;
220 unique_ptr<Test, custom_deleter<Test> > up_custom_dele(new Test(), d);
221
222 cout << "operator ->: " << endl;
223 up_custom_dele->method();
224
225 cout << "operator *: " << endl;
226 (*up_custom_dele).method();
227
228 cout << "operator bool: " << endl;
229 if(up_custom_dele){ cout<< "obj is exit" << endl;}
230
231 cout << "get: " << endl;
232 up_custom_dele.get()->method();
233
234 cout << "getDeleter: " << endl;
235 custom_deleter<Test> custom_del = up_custom_dele.getDeleter();
236 custom_del.deleter_method();
237
238 cout << "release: " << endl;
239 unique_ptr<Test> up3(up_custom_dele.release());
240
241 //if take this, will die
242 //(*up_custom_dele).method();
243
244 cout << "reset: " << endl;
245 up3.reset();
246
247
248 return 0;
249 }
执行代码,打印如下:
1 [root@localhost code]# g++ -o unique unique_ptr_implement.cpp 2 [root@localhost code]# ./unique 3 =======default deleter====interface test begin: ========== 4 construct.. 5 operator ->: 6 welcome Test.. 7 operator *: 8 welcome Test.. 9 operator bool: 10 obj is exit 11 get: 12 welcome Test.. 13 getDeleter: 14 deleter method... 15 release: 16 reset: 17 default deleter..... 18 destruct.. 19 =======Custom deleter====interface test begin: ========== 20 construct.. 21 operator ->: 22 welcome Test.. 23 operator *: 24 welcome Test.. 25 operator bool: 26 obj is exit 27 get: 28 welcome Test.. 29 getDeleter: 30 custom deleter method... 31 release: 32 reset: 33 default deleter..... 34 destruct.. 35 [root@localhost code]#
从实现结果可以看出,unique_ptr保证一个动态对象只有一个unique_ptr对象所拥有,unique_ptr对象之间无法copy和赋值,只能进行动态内存对象的转移,转移时,原有的unique_ptr对象将不再拥有动态内存的访问权限,这样可以保证动态内存使用的安全性。在实现中构造函数提供了两个,一个使用默认删除器,另一个则需要我们构造时传入删除器,这样可以很好的进行资源自定义删除。 对于多个指针对象指向同一个动态内存对象,unique_ptr不适用,需使用share_ptr
来源:https://www.cnblogs.com/blog-yejy/p/8972858.html