-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshared_ptr.cpp
130 lines (108 loc) · 2.61 KB
/
shared_ptr.cpp
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
/**
* 自实现shared_ptr
*/
#include <cstdio>
#include <cstring>
template<typename T>
class shared_ptr {
public:
//无参构造函数,默认初始为空指针
shared_ptr() = default;
//裸指针转移资源管理权
explicit shared_ptr(T *ptr) : mPtr(ptr) {
addRefer();
}
//智能指针共享资源
shared_ptr(const shared_ptr<T> &sharedPtr)
: mPtr(sharedPtr.mPtr), mRefCount(sharedPtr.mRefCount) {
addRefer();
}
shared_ptr<T> &operator=(const shared_ptr<T> &sharedPtr) {
//排除自赋值情况
if (this != &sharedPtr) {
removeRefer();
mPtr = sharedPtr.mPtr;
mRefCount = sharedPtr.mRefCount;
addRefer();
}
return *this;
}
~shared_ptr() {
removeRefer();
}
//解引用
T &operator*() const {
return *mPtr;
}
//ptr->mem
//如果ptr是内置指针,等价于(*ptr).mem
//如果ptr是类对象,等价于(ptr.operator->())->mem
T *operator->() const {
return mPtr;
//相当于return &this->operator*();
}
//转换为bool类型的规则
explicit operator bool() const {
return mPtr;
}
private:
T *mPtr = nullptr;
int *mRefCount = nullptr;
void addRefer() {
//空指针不改变引用计数
if (!mPtr) return;
if (mRefCount) {
++(*mRefCount);
} else {
mRefCount = new int(1);
}
}
void removeRefer() {
//空指针不改变引用计数
if (!mPtr) return;
if (mRefCount) {
--(*mRefCount);
if (*mRefCount == 0) {
delete mRefCount;
delete mPtr;
mRefCount = nullptr;
mPtr = nullptr;
}
}
}
};
class Test {
private:
char name[20]{};
public:
explicit Test(const char *str) {
strcpy(name, str);
printf("%s constructor\n", name);
}
void test() {
printf("%s test\n", name);
}
~Test() {
printf("%s destructor\n", name);
}
};
void print(void *ptr) {
int *mPtr = *reinterpret_cast<int **>(ptr);
int *mRefCount = *(reinterpret_cast<int **>(ptr) + 1);
int count = 0;
if (mRefCount != nullptr) count = *mRefCount;
printf("addr: 0x%x count: %d\n", mPtr, count);
}
int main() {
shared_ptr<Test> ptr1;
print(&ptr1);
shared_ptr<Test> ptr2(new Test("test2 "));
print(&ptr2);
shared_ptr<Test> ptr3(ptr2);
print(&ptr3);
ptr1 = ptr3;
print(&ptr1);
ptr1->test();
if (ptr1) (*ptr3).test();
return 0;
}