文章目录
- 前言
- 一、shared_ptr与weak_ptr是什么?
- 1.shared_ptr的内存模型
- 2.weak_ptr的内存模型
- 二、仿写系统的shared_ptr与weak_ptr
- 1.mdeletor
- 2.Ref_con
- 3.shared_ptr
- 4.weak_ptr
- 三、解决循环引用问题
- 四、总结
前言
简单介绍shared_ptr与weak_ptr,仿写系统的shared_ptr与weak_ptr,并解决循环引用的问题.
提示:以下是本篇文章正文内容,下面案例可供参考
一、shared_ptr与weak_ptr是什么?
shared_ptr是一种智能指针(smart pointer),作用有如同指针,但会记录有多少个shared_ptrs共同指向一个对象。这便是所谓的引用计数(reference counting)。一旦最后一个这样的指针被销毁,也就是一旦某个对象的引用计数变为0,这个对象会被自动删除。
weak_ptr是为配合shared_ptr而引入的一种智能指针。
1.shared_ptr的内存模型
2.weak_ptr的内存模型
二、仿写系统的shared_ptr与weak_ptr
1.mdeletor
```cpp
class Mdeletor
{
public:
Mdeletor() = default;
void operator()(_Ty* p)const
{
if (p != NULL)
{
delete p;
}
p = NULL;
}
};
template<typename _Ty>
class Mdeletor<_Ty[]>
{
public:
Mdeletor() = default;
void operator()(_Ty* p)const
{
if (p != NULL)
{
delete[]p;
}
p = NULL;
}
};
2.Ref_con
template<typename _Ty>
class RefCnt
{
protected:
_Ty* ptr;
std::atomic_int Uses;
std::atomic_int Weaks;
public:
RefCnt(_Ty* p) :ptr(p), Uses(1), Weaks(1) {}
~RefCnt() {}
void IncUses()
{
Uses += 1;
}
void IncWeaks()
{
Weaks += 1;
}
template<typename _Ty, typename _Dx>
friend class my_shared_ptr;
template<typename _Ty>
friend class my_weak_ptr;
};
3.shared_ptr
代码如下(示例):
template<typename _Ty,typename _Dx= Mdeletor<_Ty>>
class my_shared_ptr
{
private:
_Ty* Ptr;
RefCnt<_Ty>* Ref;
_Dx mdeletor;
public:
my_shared_ptr(_Ty* p = nullptr) :Ptr(nullptr),Ref(nullptr)
{
if (p != nullptr)
{
Ptr = p;
Ref = new RefCnt<_Ty>(p);
}
}
my_shared_ptr(const my_shared_ptr& other):Ptr(other.Ptr),Ref(other.Ref)
{
if (Ptr != NULL)
{
Ref->IncUses();
}
}
my_shared_ptr(my_shared_ptr&& other) :Ptr(other.Ptr), Ref(other.Ref)
{
other.Ptr = NULL;
other.Ref = NULL;
}
my_shared_ptr& operator=(const my_shared_ptr& other)
{
if (this == &other || Ptr == other.Ptr) return *this;
if (Ptr != NULL && --Ref->Uses == 0)
{
mdeletor(Ptr);
if (--Ref->Weaks == 0)
{
delete Ref;
Ref = NULL;
}
}
Ptr = other.Ptr;
Ref = other.Ref;
if (Ptr != NULL)
{
Ref->IncUses();
}
return *this;
}
my_shared_ptr& operator=(my_shared_ptr&& other)
{
if (this == &other) return *this;
if (Ptr == other.Ptr && Ptr != NULL)
{
other.Ptr = NULL;
other.Ref = NULL;
Ref->Uses -= 1;
return *this;
}
if (Ptr != NULL && --Ref->Uses == 0)
{
mdeletor(Ptr);
if (--Ref->Weaks == 0)
{
delete Ref;
Ref = NULL;
}
}
Ptr = other.Ptr;
Ref = other.Ref;
other.Ptr = NULL;
other.Ref = NULL;
return *this;
}
~my_shared_ptr()
{
if (Ptr != NULL && --Ref->Uses == 0)
{
mdeletor(Ptr);
if (--Ref->Weaks == 0)
{
delete Ref;
}
}
Ref = NULL;
}
_Ty* get()const
{
return Ptr;
}
_Ty& operator*()
{
return *get();
}
_Ty* operator->()
{
return get();
}
size_t use_count()const
{
if (Ref == NULL) return 0;
return Ref->Uses;
}
void swap(my_shared_ptr& other)
{
std::swap(Ptr, other.Ptr);
std::swap(Ref, other.Ref);
}
operator bool()const
{
return Ptr != NULL;
}
template<typename _Ty>
friend class my_weak_ptr;
};
4.weak_ptr
代码如下(示例):
template<typename _Ty>
class my_weak_ptr
{
private:
RefCnt<_Ty>* wRef;
public:
my_weak_ptr() :wRef(NULL) {}
my_weak_ptr(const my_shared_ptr<_Ty>& other) :wRef(other.Ref)
{
if (wRef!=NULL)
{
wRef->IncWeaks();
}
}
my_weak_ptr(const my_weak_ptr& other) :wRef(other.wRef)
{
if (wRef != NULL)
{
wRef->IncWeaks();
}
}
my_weak_ptr(my_weak_ptr&& other) :wRef(other.wRef)
{
other.wRef = NULL;
}
my_weak_ptr& operator=(const my_weak_ptr& other)
{
if (this == &other||wRef=other.wRef) return *this;
if (this != NULL && --wRef->Weaks == 0)
{
delete wRef;
}
wRef = other.wRef;
if (wRef != NULL)
{
wRef->IncUses();
}
return *this;
}
my_weak_ptr& operator=(my_weak_ptr&& other)
{
if (this == &other) return *this;
if (wRef == other.wRef && wRef != NULL)
{
other.wRef = NULL;
wRef->Weaks -= 1;
return *this;
}
if (this != NULL && --wRef->Weaks == 0)
{
delete wRef;
}
wRef = other.wRef;
other.wRef = NULL;
return *this;
}
my_weak_ptr& operator=(const my_shared_ptr<_Ty>& other)
{
if (wRef == other.Ref) return *this;
if (wRef != NULL && --wRef->Uses == 0)
{
delete wRef;
}
wRef = other.Ref;
if (wRef != NULL)
{
wRef->IncWeaks();
}
return *this;
}
my_weak_ptr& operator=( my_shared_ptr<_Ty>&& other) = delete;
~my_weak_ptr()
{
if (wRef != NULL && --wRef->Weaks == 0)
{
delete wRef;
}
wRef = NULL;
}
bool expired()const
{
return wRef->Uses == 0;
}
my_shared_ptr<_Ty> lock()const
{
my_shared_ptr<_Ty>tmp;
tmp.Ptr = wRef->ptr;
tmp.Ref = wRef;
tmp.Ref->IncUses();
return tmp;
}
};
该处使用的url网络请求的数据。
三、解决循环引用问题
四、总结
weak_ptr一般需要与shared_ptr联合使用,且若要使用weak_ptr时需要用lock()函数返回一个shared_ptr的对象再进行使用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)