Weak pointer的实现方法.
1
#include <assert.h>
2
#include <map>
3
#include <stdio.h>
4
5
// memory leak checker
6
struct Value
7
{
8
bool valid;
9
int line;
10
11
Value()
12
:valid(false), line(-1)
13
{}
14
15
Value(bool v, int l)
16
:valid(v), line(l)
17
{
18
}
19
};
20
21
typedef std::map<void*, Value> ContainerType;
22
ContainerType myMap;
23
24
#define mynew(x) mynew_(x, __LINE__)
25
26
void checkMemory()
27
{
28
size_t n = myMap.size();
29
//assert(n==0);
30
31
if(n>0)
32
{
33
printf("Memory leak found:\n");
34
for (ContainerType::const_iterator it=myMap.begin();
35
it!=myMap.end();++it)
36
{
37
printf("Line %d\n", it->second.line);
38
}
39
assert(0);
40
}
41
}
42
43
template <class T>
44
T* mynew_(T const &n, int line)
45
{
46
T* p = (T*)malloc(sizeof(T));
47
*p = n;
48
myMap[p]=Value(true, line);
49
return p;
50
}
51
52
void mydelete(void* p)
53
{
54
ContainerType::iterator it = myMap.find(p);
55
assert(it!=myMap.end());
56
myMap.erase(it);
57
free(p);
58
}
59
60
class AutoPtr
61
{
62
public:
63
explicit AutoPtr(int *p=0)
64
:p_(p), refCnt_(mynew(int(1))), valid_(mynew(bool(p?true:false)))
65
{}
66
67
~AutoPtr()
68
{
69
if(p_)
70
{
71
mydelete (p_);
72
}
73
74
(*refCnt_)--;
75
76
*valid_ = false;
77
78
assert(*refCnt_>=0);
79
if(*refCnt_==0)
80
{
81
mydelete(refCnt_);
82
mydelete(valid_);
83
}
84
}
85
86
bool empty() const
87
{
88
if(!*valid_)
89
assert(p_==0);
90
else
91
assert(p_!=0);
92
93
return !(*valid_);
94
}
95
private:
96
friend class WeakPtr;
97
AutoPtr(const AutoPtr&);
98
AutoPtr& operator =(const AutoPtr&);
99
100
int *p_;
101
bool *valid_;
102
int *refCnt_; //weak ref cnt, always valid if one weakPtr or AutoPtr exist
103
};
104
105
class WeakPtr
106
{
107
public:
108
// ctor
109
WeakPtr()
110
:p_(0), refCnt_(mynew(int(1))), valid_(mynew(bool(false)))
111
{
112
}
113
114
explicit WeakPtr(AutoPtr& p) //p must be valid
115
:p_(&p), refCnt_(p.refCnt_),valid_(p.valid_)
116
{
117
(*p_->refCnt_)++;
118
}
119
120
WeakPtr(const WeakPtr& rhs) //p must be valid
121
{
122
construct(rhs);
123
}
124
125
~WeakPtr()
126
{
127
destroy();
128
}
129
130
// get
131
bool empty() const
132
{
133
assert((*refCnt_)>=0);
134
return !(*valid_);
135
}
136
137
// operator
138
WeakPtr& operator=(const WeakPtr &rhs)
139
{
140
if(this!=&rhs)
141
{
142
destroy();
143
construct(rhs);
144
}
145
return *this;
146
}
147
148
private:
149
void destroy()
150
{
151
(*refCnt_)--;
152
153
assert((*refCnt_)>=0);
154
if(0==*refCnt_)
155
{
156
mydelete(refCnt_);
157
mydelete(valid_);
158
}
159
160
}
161
void construct(const WeakPtr &rhs)
162
{
163
p_ = rhs.p_;
164
refCnt_ = rhs.refCnt_;
165
valid_ = rhs.valid_;
166
(*refCnt_)++;
167
}
168
169
AutoPtr *p_;
170
bool *valid_;
171
int *refCnt_; //weak ref cnt, always valid if one weakPtr or AutoPtr exist
172
};
173
174
void Test()
175
{
176
WeakPtr p1;
177
178
assert(p1.empty());
179
{
180
AutoPtr p(mynew(int(100)));
181
p1 = WeakPtr(p);
182
assert(!p1.empty());
183
assert(!p.empty());
184
}
185
assert(p1.empty());
186
187
//mynew(int());
188
}
189
190
void main()
191
{
192
Test();
193
checkMemory();
194
}

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

- 上一篇 Linux安装与启动
- 下一篇 一个数据包经过路由器和交换机各会发生什么变化.