智能指针的简单实现
爱吃鱼的猫 Lv2

shared_ptr的简单实现(非线程安全)

主要包括以下成员函数:

  1. 构造函数

  2. 析构函数

  3. 拷贝构造函数

  4. operator=()

  5. operator*()

  6. operator->()

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
#include <iostream>
#include <cassert>

using namespace std;

template<typename T>
class shared_ptr{
private:
size_t* p_count;
T* ptr;
public:
explicit shared_ptr(T* _ptr = nullptr):ptr(_ptr){
if(ptr) p_count = new size_t(1);
else p_count = new size_t(0);
}

shared_ptr(const shared_ptr<T>& rhs){
ptr = rhs.ptr;
p_count = rhs.p_count;
(*p_count)++;
}

/* 返回引用是为了满足连续复制 比如A=B=C=1 */
shared_ptr<T>& operator=(const shared_ptr<T>& rhs){
/* 处理“自我赋值” */
if(this == &rhs) return *this;

/* 如果shared_ptr之前指向一个对象,则需要释放掉相应资源 */
if(ptr){
(*p_count)--;
if((*p_count)==0){
delete ptr;
delete p_count;
}
}

/* 复制对象,并增加计数 */
ptr = rhs.ptr;
p_count = rhs.p_count;
(*p_count)++;
return *this;
}

/* 重载* */
T& operator*(){
assert(ptr);
return *ptr;
}

/* 重载-> */
T* operator->(){
assert(ptr);
return ptr;
}

size_t use_count() const {
return *p_count;
}

~shared_ptr(){
(*p_count)--;
if((*p_count)==0){
delete ptr;
delete p_count;
}
}
};

class test{
public:
int a = 1;
};

int main(){
shared_ptr<test> p1(new test); // 默认构造函数
cout<<p1->a<<endl;
cout<<(*p1).a<<endl;
{
shared_ptr<test> p2(p1); // 拷贝构造函数
cout<<"p2:"<<p2.use_count()<<endl;
shared_ptr<test> p3 = p2; // 拷贝构造函数
cout<<"p2:"<<p2.use_count()<<endl;
cout<<"p3:"<<p3.use_count()<<endl;

shared_ptr<test> p4(new test);
cout<<"Before p4:"<<p4.use_count()<<endl;
p4 = p3; // operator= 赋值
cout<<"After p4:"<<p4.use_count()<<endl;
}
cout<<"p1:"<<p1.use_count()<<endl;
}

unique_ptr的简单实现

主要包括一下成员函数:

  1. 构造函数;

  2. 移动构造函数;

  3. 析构函数;

  4. 禁用拷贝构造函数;

  5. 禁用拷贝赋值函数 operator=();

  6. reset(): 释放源资源,指向新资源;

  7. release(): 返回资源,放弃对资源的管理;

  8. get(): 返回资源,只是公外部使用,依然管理资源;

  9. operator bool(): 是否持有资源;

  10. operator*();

  11. operator->();

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
#include <iostream>
#include <cassert>

template<typename T>
class unique_ptr{
private:
T* ptr;

public:
unique_ptr(T* _ptr):ptr(_ptr){};
/* 移动构造函数 */
unique_ptr(unique_ptr&& rhs):ptr(rhs.release()){};

~unique_ptr(){
if(ptr) delete ptr;
ptr = nullptr;
}

/* 需要禁止的默认成员函数 */
unique_ptr(const unique_ptr& rhs) = delete;
unique_ptr& operator=(const unique_ptr& rhs) = delete;

public:
/* 释放源资源,指向新资源 */
void reset(T* _ptr){
if(ptr) delete ptr;
ptr = _ptr;
}

/* 返回资源,放弃对资源的管理 */
T* release(){
T* pTemp = ptr;
ptr = nullptr;
return pTemp;
}
/* 返回资源,只是公外部使用,依然管理资源 */
T* get(){
return ptr;
}

public:
/* 重载bool() */
explicit operator bool() const{
return ptr != nullptr;
}

T& operator*(){
assert(ptr);
return *ptr;
}

T* operator->(){
assert(ptr);
return ptr;
}
};

class test{
public:
int a = 1;
};

int main(){
unique_ptr<test> x(new test);
cout<<"x->a:"<<(*x).a<<endl;
unique_ptr<test> y = move(x);
//test* aaa = x.get();
if(!x) cout<<"Moved x!!"<<endl;
cout<<"y->a:"<<y->a<<endl;
}

参考文献:

[1] https://zhuanlan.zhihu.com/p/344953368

[2] https://www.ccppcoding.com/archives/202

  • Post title:智能指针的简单实现
  • Post author:爱吃鱼的猫
  • Create time:2022-05-06 09:31:04
  • Post link:https://djtang.github.io/2022/05/06/智能指针的简单实现/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.
 Comments