智能指针的简单实现

SharedPtr & WeakPtr

RefCounter

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
/**
* 引用计数器
*/
template<class T>
class RefCounter
{
public:
RefCounter(T* value_) : value(value_) {}
~RefCounter() {}

int GetRefCount() const
{
return refCount;
}

int GetWeakRefCount() const
{
return weakRefCount;
}

void IncRef()
{
refCount++;
weakRefCount++;
}

/* 计数不为0才增加计数 */
bool IncRefIfNotZero()
{
if (refCount) {
IncRef();
return true;
}
return false;
}

void DecRef()
{
if (--refCount == 0) {
FreeValue();
}
if (--weakRefCount == 0) {
FreeSelf();
}
}

void IncWeakRef()
{
weakRefCount++;
}

void DecWeakRef()
{
if (--weakRefCount == 0) {
FreeSelf();
}
}

void FreeValue()
{
delete value;
value = nullptr;
}

void FreeSelf()
{
this->~RefCounter();
delete this;
}

private:
int refCount = 1; // 强引用计数
int weakRefCount = 1; // 弱引用计数

T* value; // 资源
};

SharedPtr

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
template<class T> class WeakPtr;

/*
* 强引用
*/
template<class T>
class SharedPtr
{
public:
SharedPtr() {}
SharedPtr(T* value_ = nullptr) // 构造
{
if (value_) {
AllocImpl(value_);
}
}

SharedPtr(const SharedPtr& sharedPtr) // 拷贝构造
: refCounter(sharedPtr.refCounter)
, value(sharedPtr.value)
{
if (refCounter) {
refCounter->IncRef();
}
}

SharedPtr(SharedPtr&& sharedPtr) // 移动构造
: refCounter(sharedPtr.refCounter)
, value(sharedPtr.value)
{
sharedPtr.refCounter = nullptr;
sharedPtr.value = nullptr;
}

SharedPtr(const WeakPtr<T>& weakPtr)
{
if (weakPtr.refCounter && weakPtr.refCounter->IncRefIfNotZero()) { // weak的资源有效时才增加计数
refCounter = weakPtr.refCounter;
value = weakPtr.value;
}
}

~SharedPtr() // 析构
{
if (refCounter) {
refCounter->DecRef();
refCounter = nullptr;
value = nullptr;
}
}

SharedPtr& operator=(const SharedPtr& sharedPtr) // 拷贝赋值
{
if (&sharedPtr != this) {
SharedPtr(sharedPtr).Swap(*this);
}
return *this;
}

SharedPtr& operator=(SharedPtr&& sharedPtr) // 移动赋值
{
if (&sharedPtr != this) {
SharedPtr(move(sharedPtr)).Swap(*this);
}
return *this;
}

int UseCount() const
{
return refCounter ? refCounter->GetRefCount() : 0;
}

T* Get() const
{
return value;
}

void Swap(SharedPtr& sharedPtr)
{
swap(value, sharedPtr.value);
swap(refCounter, sharedPtr.refCounter);
}

void Reset(T* value_ = nullptr)
{
SharedPtr(value_).Swap(*this);
}

private:
template<class T> friend class WeakPtr;

RefCounter<T>* refCounter = nullptr; // 计数器
T* value = nullptr; // 资源

void AllocImpl(T* value_) {
refCounter = new RefCounter<T>(value_);
value = value_;
}
};

WeakPtr

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
/*
* 弱引用
*/
template<class T>
class WeakPtr {
public:
WeakPtr(const WeakPtr& weakPtr) // 拷贝构造
: refCounter(weakPtr.refCounter)
, value(weakPtr.value)
{
if (refCounter) {
refCounter->IncWeakRef();
}
}

/* 其它构造和赋值... */

~WeakPtr() // 析构
{
if (refCounter) {
refCounter->DecWeakRef();
}
}

bool Expired() const
{
return !refCounter || refCounter->GetRefCount() == 0;
}

SharedPtr<T> Lock()
{
return SharedPtr<T>(*this);
}

private:
RefCounter<T>* refCounter = nullptr; // 计数器
T* value = nullptr; // 资源,不提供外部访问
};

EnableSharedFromThis

EnableSharedFromThis

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
template<class T>
class EnableSharedFromThis
{
public:
using _ESFT_TYPE = EnableSharedFromThis; // 类型标识

SharedPtr<T> SharedFromThis() // 返回自身强引用
{
return SharedPtr<T>(_enableSharedWeakPtr);
}

WeakPtr<T> WeakFromThis() // 返回自身弱引用
{
return _enableSharedWeakPtr;
}

protected:
EnableSharedFromThis() : _enableSharedWeakPtr()
{
}

EnableSharedFromThis& operator=(const EnableSharedFromThis&)
{
return *this;
}

~EnableSharedFromThis() = default;

private:
template<class T>
friend class SharedPtr;

mutable WeakPtr<T> _enableSharedWeakPtr; // 对自身的弱引用
};

CanEnableShared

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template<class T, class = void>
struct CanEnableShared : false_type {};

template<class T>
struct CanEnableShared<T, void_t<typename T::_ESFT_TYPE>>
: is_convertible<remove_cv_t<T>*, typename T::_ESFT_TYPE*>::type {
}; // verify unambiguous inheritance

SharedPtr::SharedPtr(T* t)
{
// ...SharedPtr构造之后
if constexpr (conjunction_v<CanEnableShared<T>>)
{
if(t && t->_enableSharedWeakPtr.expired())
{
t->_enableSharedWeakPtr = *this; // 设置弱引用
}
}
}