-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsimple_shared_ptr.cpp
More file actions
133 lines (110 loc) · 3.03 KB
/
simple_shared_ptr.cpp
File metadata and controls
133 lines (110 loc) · 3.03 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
#include<iostream>
#include<cassert>
template<typename T>
struct ControlBlock{
T* ptr;
size_t shared_count;
size_t weak_count;
ControlBlock(T *p):ptr(p), shared_count(1), weak_count(0){
}
void inc_shared(){
++shared_count;
}
void dec_shared(){
if(--shared_count == 0){
delete ptr;
if(weak_count == 0){
delete this;
}
}
}
};
template<typename T>
class SimpleSharedPtr{
public:
explicit SimpleSharedPtr(T *p = nullptr):ptr_(p), block_(p ? new ControlBlock<T>(p) : nullptr){}
SimpleSharedPtr(const SimpleSharedPtr& other):ptr_(other.ptr_), block_(other.block_){
if(block_){
block_->inc_shared();
}
}
SimpleSharedPtr(SimpleSharedPtr&& other) noexcept:ptr_(other.ptr_), block_(other.block_) {
other.ptr_ = nullptr;
other.block_ = nullptr;
}
SimpleSharedPtr& operator=(const SimpleSharedPtr& other){
if(this != other){
reset(); // 释放资源
ptr_ = other.ptr_;
block_ = other.block_;
if(block_){
block_ = block_->inc_shared();
}
}
return *this;
}
SimpleSharedPtr& operator=(SimpleSharedPtr&& other) noexcept {
if(this != other){
reset(); // 释放资源
ptr_ = other.ptr_;
block_ = other.block_;
other.ptr_ = nullptr;
other.block_ = nullptr;
}
return *this;
}
~SimpleSharedPtr(){
reset();
}
T& operator*() const { return *ptr_;}
T* operator->() const { return ptr_;}
T* get() const { return ptr_;}
size_t use_count() const {return block_ ? block_->shared_count:0;}
bool unique() const { return use_count() == 1;}
void reset(){
if(block_){
block_->dec_shared();
}
ptr_ = nullptr;
block_ = nullptr;
}
private:
T* ptr_;
ControlBlock<T>* block_;
};
// ===== 测试用例 =====
struct TestObj {
int id;
static int count;
TestObj(int i) : id(i) { ++count; std::cout << "Construct " << id << "\n"; }
~TestObj() { --count; std::cout << "Destruct " << id << "\n"; }
};
int TestObj::count = 0;
void test_basic() {
std::cout << "\n--- Basic Test ---\n";
auto p1 = SimpleSharedPtr<TestObj>(new TestObj(1));
assert(p1.use_count() == 1);
auto p2 = p1; // 拷贝
assert(p1.use_count() == 2);
assert(p2.use_count() == 2);
auto p3 = std::move(p1); // 移动
assert(p1.get() == nullptr);
assert(p3.use_count() == 2); // p2 和 p3 共享
p2.reset();
assert(p3.use_count() == 1);
}
void test_lifetime() {
std::cout << "\n--- Lifetime Test ---\n";
assert(TestObj::count == 0);
{
auto p = SimpleSharedPtr<TestObj>(new TestObj(2));
assert(TestObj::count == 1);
}
assert(TestObj::count == 0); // 离开作用域自动析构
}
int main() {
test_basic();
test_lifetime();
std::cout << "\n✅ All tests passed!\n";
return 0;
}