-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathReferencedPtr.cpp
More file actions
137 lines (116 loc) · 2.18 KB
/
ReferencedPtr.cpp
File metadata and controls
137 lines (116 loc) · 2.18 KB
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
/*
* author: Maxiaoyuan
* date: 2017/8/11
* Implement shared_ptr on my own. All the functions are following the STL library.
*/
#include<memory>
#include<iostream>
using namespace std;
typedef unsigned int uint32;
string get() {
cout<<"get called"<<endl;
return "abc";
}
class A {
public:
A() {
cout<<"A"<<endl;
}
void f() {
cout<<"f()"<<endl;
}
~A() {
cout<<"~A"<<endl;
}
string tmp = get();
};
//Main class
template<class T> class ReferencedPtr {
public:
ReferencedPtr() {
cout<<"ReferencedPtr()"<<endl;
instance_ = NULL;
count_ = NULL;
}
ReferencedPtr(T * instance) {
cout<<"ReferencedPtr(T*)"<<endl;
instance_ = instance;
count_ = new atomic<uint32>(0);
(*count_)++;
}
ReferencedPtr(ReferencedPtr& r): ReferencedPtr() {
if(r.instance_) {
(*r.count_)++;
count_ = r.count_;
}
}
//move constructor
ReferencedPtr(ReferencedPtr&& r) nothrow {
instance_ = r.instance_;
count_ = r.count_;
r.instance_ = NULL;
r.count_ = NULL;
}
~ReferencedPtr() {
cout<<"~ReferencedPtr()"<<endl;
reset();
}
T* get() {
return instance_;
}
uint32 use_count() {
if(!count_) return 0;
return *count_;
}
ReferencedPtr& operator = (ReferencedPtr & r) {
reset();
if(r.instance_) {
(*r.count_)++;
count_ = r.count_;
instance_ = r.instance_;
}
return *this;
}
bool operator == (const ReferencedPtr& r) const {
return instance_ == r.instance_;
}
explicit operator bool() {
return instance_ != NULL;
}
T * operator -> () {
return instance_;
}
T & operator * () {
return *instance_;
}
//we don't have nullptr, so we must use a reset function explicitly
void reset() {
if(!instance_) return;
(*count_)--;
if(*count_ == 0) {
delete instance_;
delete count_;
}
instance_ = NULL;
count_ = NULL;
}
private:
T * instance_ = NULL;
atomic<uint32> * count_ = NULL;
};
struct nullptr_t: public ReferencedPtr
typedef ReferencedPtr<A> ptr_A;
int main()
{
A * pa = new A();
ptr_A p1(pa);
ptr_A p2 = p1;
ptr_A p3 = p1;
cout<<p1.use_count()<<endl;
cout<<p2.use_count()<<endl;
cout<<p3.use_count()<<endl;
p1.release();
cout<<p1.use_count()<<endl;
cout<<p2.use_count()<<endl;
cout<<p3.use_count()<<endl;
}