智能指针(move sementic)

文章目录
  1. 1. 参考资料
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
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
#ifndef SMART_PTR_H
#define SMART_PTR_H

#include <atomic> // std::atomic
#include <utility> // std::swap

class shared_count {
public:
shared_count() noexcept
: count_(1)
{
}
void add_count() noexcept
{
count_.fetch_add(1, std::memory_order_relaxed);
}
long reduce_count() noexcept
{
return --count_;
}
long get_count() const noexcept
{
return count_;
}

private:
std::atomic_long count_;
};

template <typename T>
class smart_ptr {
public:
template <typename U>
friend class smart_ptr;

explicit smart_ptr(T* ptr = nullptr)
: ptr_(ptr)
{
if (ptr) {
shared_count_ = new shared_count();
}
}
~smart_ptr()
{
if (ptr_ && !shared_count_->reduce_count()) {
delete ptr_;
delete shared_count_;
}
}

smart_ptr(const smart_ptr& other) noexcept
{
ptr_ = other.ptr_;
if (ptr_) {
other.shared_count_->add_count();
shared_count_ = other.shared_count_;
}
}
template <typename U>
smart_ptr(const smart_ptr<U>& other) noexcept
{
ptr_ = other.ptr_;
if (ptr_) {
other.shared_count_->add_count();
shared_count_ = other.shared_count_;
}
}
template <typename U>
smart_ptr(smart_ptr<U>&& other) noexcept
{
ptr_ = other.ptr_;
if (ptr_) {
shared_count_ = other.shared_count_;
other.ptr_ = nullptr;
}
}
template <typename U>
smart_ptr(const smart_ptr<U>& other, T* ptr) noexcept
{
ptr_ = ptr;
if (ptr_) {
other.shared_count_->add_count();
shared_count_ = other.shared_count_;
}
}
smart_ptr& operator=(smart_ptr rhs) noexcept
{
rhs.swap(*this);
return *this;
}

T* get() const noexcept
{
return ptr_;
}
long use_count() const noexcept
{
if (ptr_) {
return shared_count_->get_count();
} else {
return 0;
}
}
void swap(smart_ptr& rhs) noexcept
{
using std::swap;
swap(ptr_, rhs.ptr_);
swap(shared_count_, rhs.shared_count_);
}

T& operator*() const noexcept
{
return *ptr_;
}
T* operator->() const noexcept
{
return ptr_;
}
operator bool() const noexcept
{
return ptr_;
}

private:
T* ptr_;
shared_count* shared_count_;
};

template <typename T>
void swap(smart_ptr<T>& lhs, smart_ptr<T>& rhs) noexcept
{
lhs.swap(rhs);
}

template <typename T, typename U>
smart_ptr<T> static_pointer_cast(const smart_ptr<U>& other) noexcept
{
/** static_cast
①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。
③把空指针转换成目标类型的空指针。
④把任何类型的表达式转换成void类型。
注意:static_cast不能转换掉expression的const、volatile、或者__unaligned属性
*/
T* ptr = static_cast<T*>(other.get());
return smart_ptr<T>(other, ptr);
}

template <typename T, typename U>
smart_ptr<T> reinterpret_pointer_cast(const smart_ptr<U>& other) noexcept
{
//用于进行各种不同类型的指针之间、不同类型的引用之间以及指针和能容纳
//指针的整数类型之间的转换。转换时,执行的是逐个比特复制的操作。
T* ptr = reinterpret_cast<T*>(other.get());
return smart_ptr<T>(other, ptr);
}

template <typename T, typename U>
smart_ptr<T> const_pointer_cast(const smart_ptr<U>& other) noexcept
{
T* ptr = const_cast<T*>(other.get());
return smart_ptr<T>(other, ptr);
}

template <typename T, typename U>
smart_ptr<T> dynamic_pointer_cast(const smart_ptr<U>& other) noexcept
{
T* ptr = dynamic_cast<T*>(other.get());
return smart_ptr<T>(other, ptr);
}

#endif // SMART_PTR_H

参考资料

  • [现代c++实战30讲]