- 前言
- 一、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而引入的一种智能指针。
```cpp
class Mdeletor
{
public:
Mdeletor() = default;
void operator()(_Ty* p)const
{
if (p != NULL)
{
delete p;
}
p = NULL;
}
};
template
class Mdeletor<_Ty[]>
{
public:
Mdeletor() = default;
void operator()(_Ty* p)const
{
if (p != NULL)
{
delete[]p;
}
p = NULL;
}
};
2.Ref_con
template3.shared_ptrclass 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 friend class my_shared_ptr; template friend class my_weak_ptr; };
代码如下(示例):
template4.weak_ptr> 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的使用权 other.Ref = NULL; Ref->Uses -= 1;//强引用计数-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 friend class my_weak_ptr; };
代码如下(示例):
templateclass 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) { //1 判断是否自赋值 if (this == &other) return *this; //2 判断是否是指向同一个对象的两个指针相互赋值 if (wRef == other.wRef && wRef != NULL)//如果是 { other.wRef = NULL; wRef->Weaks -= 1; return *this; } //3 两个指向不同对象的指针赋值 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的对象再进行使用。



