一、关于shared_ptr

定义于头文件

1
2
template< class T > class shared_ptr;
//(C++11 起)

std::shared_ptr 是通过指针保持对象共享所有权的智能指针。多个 shared_ptr 对象可占有同一对象。
下列情况之一出现时销毁对象并解分配其内存:

  • 最后剩下的占有对象的 shared_ptr 被销毁;
  • 最后剩下的占有对象的 shared_ptr 被通过 operator= 或 reset() 赋值为另一指针。

二、shared_ptr对象内存结构

在这里插入图片描述

三、仿写代码

shared_ptr

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
#ifndef SHARED_PTR_H
#define SHARED_PTR_H
#include <iostream>
using namespace std;
namespace pzj
{
//单个对象删除器
template<class _Ty>
class Deleter
{
Deleter() = default;
public:
void operator()(_Ty* p = NULL)const
{
if (p != NULL)
{
delete p;
}
}
};
//一组对象删除器
template<class _Ty>
class Deleter<_Ty[]>
{
Deleter() = default;
public:
void operator()(_Ty* p = NULL)const
{
if (p != NULL)
{
delete[] p;
}
}
};

//引用计数类
template<class _Ty>
class Rfc
{
private:
_Ty* _mptr; //存放被管理对象的地址
size_t _count; //管理者的个数
public:
Rfc(_Ty* p = NULL) : _mptr(p), _count(p != NULL) {}
~Rfc(){}
};

//单个对象版本
//shared_ptr
template<class _Ty, class Deleter_T = Deleter<_Ty>>
class shared_ptr
{
public:
shared_ptr(_Ty* p = NULL)
{
if (p != NULL)
{
_Ptr = new Rfc(p);
}
}
~shared_ptr()
{
if (_Ptr != NULL && --_Ptr->_count == 0)
{
deleter(_Ptr->_mptr);
delete _Ptr;
}
_Ptr = NULL;
}
shared_ptr(const shared_ptr& src) : _Ptr(src._Ptr)
{
if (_Ptr != NULL)
{
++_Ptr->_count;
}
}
shared_ptr(shared_ptr&& rval):_Ptr(rval._Ptr)
{
rval._Ptr = NULL;
}

shared_ptr& operator=(const shared_ptr& src)
{
if (this == &src) return *this;
if (_Ptr != NULL && --_Ptr->_count == 0)
{
deleter(_Ptr->_mptr);
delete _Ptr;
}
_Ptr = src._Ptr;
if (_Ptr != NULL)
{
++_Ptr->_count;
}
return *this;
}
shared_ptr& operator=(shared_ptr&& rval)
{
if (this == &rval) return *this;
if (_Ptr == rval._Ptr && _Ptr != NULL && rval._Ptr != NULL)
{
--_Ptr->_count;
rval._Ptr = NULL;
return *this;
}
if (_Ptr != NULL && --_Ptr->_count == 0)
{
deleter(_Ptr->_mptr);
delete _Ptr;
}
_Ptr = rval._Ptr;
rval._Ptr = NULL;
return *this;
}
void reset(_Ty* p = NULL)
{
if (_Ptr != NULL && --_Ptr->_count == 0)
{
deleter(_Ptr->_mptr);
delete _Ptr;
}
_Ptr = new Rfc(p);
}
operator bool()const
{
return _Ptr != NULL;
}
_Ty* get()const
{
return _Ptr->_mptr;
}
_Ty* operator->()
{
return get();
}
_Ty& operator*()
{
return *get();
}
size_t use_count()
{
return _Ptr->_count;
}

void swap(shared_ptr& src)
{
std::swap(_Ptr, src._Ptr);
}
private:
Rfc<_Ty>* _Ptr; //存放引用计数对象地址
Deleter_T deleter; //删除器对象
};

//多个对象版本
//shared_ptr
template<class _Ty, class Deleter_T>
class shared_ptr<_Ty[], Deleter_T>
{
public:
shared_ptr(_Ty* p = NULL)
{
if (p != NULL)
{
_Ptr = new Rfc(p);
}
}
~shared_ptr()
{
if (_Ptr != NULL && --_Ptr->_count == 0)
{
deleter(_Ptr->_mptr);
delete _Ptr;
}
_Ptr = NULL;
}
shared_ptr(const shared_ptr& src) : _Ptr(src._Ptr)
{
if (_Ptr != NULL)
{
++_Ptr->_count;
}
}
shared_ptr(shared_ptr&& rval) :_Ptr(rval._Ptr)
{
rval._Ptr = NULL;
}

shared_ptr& operator=(const shared_ptr& src)
{
if (this == &src) return *this;
if (_Ptr != NULL && --_Ptr->_count == 0)
{
deleter(_Ptr->_mptr);
delete _Ptr;
}
_Ptr = src._Ptr;
if (_Ptr != NULL)
{
++_Ptr->_count;
}
return *this;
}
shared_ptr& operator=(shared_ptr&& rval)
{
if (this == &rval) return *this;
if (_Ptr == rval._Ptr && _Ptr != NULL && rval._Ptr != NULL)
{
--_Ptr->_count;
rval._Ptr = NULL;
return *this;
}
if (_Ptr != NULL && --_Ptr->_count == 0)
{
deleter(_Ptr->_mptr);
delete _Ptr;
}
_Ptr = rval._Ptr;
rval._Ptr = NULL;
return *this;
}
void reset(_Ty* p = NULL)
{
if (_Ptr != NULL && --_Ptr->_count == 0)
{
deleter(_Ptr->_mptr);
delete _Ptr;
}
_Ptr = new Rfc(p);
}
operator bool()const
{
return _Ptr != NULL;
}
_Ty* get()const
{
return _Ptr->_mptr;
}
_Ty* operator->()
{
return get();
}
_Ty& operator*()
{
return *get();
}
size_t use_count()
{
return _Ptr->_count;
}

void swap(shared_ptr& src)
{
std::swap(_Ptr, src._Ptr);
}
//[]
_Ty& operator[](size_t index)
{
return _Ptr->_mptr[index];
}
private:
Rfc<_Ty>* _Ptr; //存放引用计数对象地址
Deleter_T deleter; //删除器对象
};
}
#endif

实际上这并不是shared_ptr的最终形态。仿写二中将讲述shared_ptr的真实形态和交叉引用的问题。但是这种实现方式尤为重要!!!