文章目录

  • 前言
  • 一、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的使用权other.Ref = NULL;Ref->Uses -= 1;//强引用计数-1return *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){//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的对象再进行使用。

C++ | shared_ptr与weak_ptr相关推荐

  1. c++11 智能指针 unique_ptr、shared_ptr与weak_ptr

    C++11中有unique_ptr.shared_ptr与weak_ptr等智能指针(smart pointer),定义在<memory>中. 可以对动态资源进行管理,保证任何情况下,已构 ...

  2. C++笔记-shared_ptr与weak_ptr需要注意的地方

    目录 基本概念 代码与实例 基本概念 share_ptr使用的是引用计数,每一个shared_ptr都指向相同的内存.只有最后一个shared_ptr析构的时候,才会释放内存,不建议直接用shared ...

  3. shared_ptr,weak_ptr使用最广范的智能指针

    一:shared_ptr 基本概念: shared_ptr通过一个引用计数,共享一个对象,shared_ptr为了解决unique_ptr在对象所有权上的局限性,在使用引用计数的机制上提供了可以共享对 ...

  4. C++2.0 shared_ptr和weak_ptr深入刨析

    在gnu c++中讨论shared_ptr和weak_ptr只需要讨论__shared_count和__weak_count,另外就是weak_ptr没有定义operator ->和operat ...

  5. C++11智能指针(unique_ptr、shared_ptr、weak_ptr)boost::scoped_ptr

    C++11智能指针(unique_ptr.shared_ptr.weak_ptr)_-码农小非-的专栏-CSDN博客_c++ shared_ptr weak_ptr 原创)智能指针拾遗 (原创)智能指 ...

  6. C++11中的智能指针unique_ptr、shared_ptr和weak_ptr详解

    目录 1.引言 2.什么是智能指针? 3.在Visual Studio中查看智能指针的源码实现 4.独占式指针unique_ptr 4.1.查看unique_ptr的源码实现片段 4.2.为什么uni ...

  7. C++智能指针:TR1的 shared_ptr 和 weak_ptr 使用介绍

    (所有示例的运行,将#序号所在main()函数去掉序号即可,参考[url]http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c15361/ ...

  8. shared_ptr和weak_ptr使用介绍

    文章目录 1 shared_ptr使用介绍 1.1 shared_ptr使用介绍 1.2 shared_ptr的使用陷阱 2 weak_ptr使用简介 1 shared_ptr使用介绍 1.1 sha ...

  9. C++11智能指针shared_ptr、weak_ptr、unique_ptr用法

    该博文为原创文章,未经博主同意不得转载,如同意转载请注明博文出处 本文章博客地址:https://cplusplus.blog.csdn.net/article/details/105065859 智 ...

最新文章

  1. 非常好!!!Linux源代码阅读——环境准备【转】
  2. python语言remove_慎用python的pop和remove方法
  3. 【自动驾驶】15.一文读懂图像中点的坐标变换(刚体变换,相似变换,仿射变换,投影变换)
  4. php生成网页,php – 网页生成(CMS喜欢)
  5. android xml 未能解析文件,Android Studio中“无法解析符号R”
  6. 如何知道远程电脑某一端口是否打开?
  7. access课程均不及格_access 第二章 查询 练习题 -
  8. Java语言学习之泛型的用法
  9. [剑指offer]面试题第[50]题[JAVA][第一个只出现一次的字符][哈希表][HashMap]
  10. 问题:lapack.so
  11. position:fixed 失效
  12. @RequestParam和@RequestBody和@PathVariable用法小结
  13. Samba 共享服务
  14. 什么短视频更吸引人?考虑到三点,吸粉引流不在话下
  15. 半年总结——思想的转变
  16. 【代码精读】CVP-MVSNet代码结构详细分析
  17. Android从网页中跳转到APP
  18. 远程连接服务器突然失败
  19. 手机的像素密度是怎么来的?
  20. 【敏捷研发系列】前端DevOps流水线实践

热门文章

  1. 整理兼职网站资源分享
  2. ajaxFileUpload连续上传文件时,从第二次开始不触发change事件
  3. 计算机网络-测试1-概述
  4. 服务器阵列信息恢复,DELL RAID阵列的创建恢复回原有的用户数据
  5. android全屏视频播放,JieCaoVideoPlayer真正实现Android的全屏视频播放
  6. 互联网产品经理常用软件及工作平台 (转)
  7. SpringBoot--->>>web-->>定制化原理
  8. 湖北省星创天地备案和绩效评价申报,2022年条件流程及时间讲解
  9. Java Date Time 教程-java.sql.Date
  10. grafana+prometheus+node_exporter Window笔记