解析c++ 中智能指针引用计数为什么不是0原理

 更新时间:2023年08月31日 10:12:13   作者:bayes  
这篇文章主要为大家介绍了C语言中智能指针引用计数为什么不是0原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

问题示例1:

#include<memory>
#include<cstdio>
#include<map>
using namespace std;
int main() {
    shared_ptr<int> ptr = make_shared<int>(100);
    printf("=%d,count=%ld\n", *ptr.get(), ptr.use_count());
    map<int, shared_ptr<int>> mp;
    mp.insert(pair<int, shared_ptr<int>>(1, ptr));
    mp.insert(pair<int, shared_ptr<int>>(2, ptr));
    printf("=%d,count=%ld\n", *ptr.get(), ptr.use_count());
    mp.clear();
    mp.clear();
    printf("=%d,count=%ld\n", *ptr.get(), ptr.use_count());
    return 0;
}

输出:
=100,count=1
=100,count=3
=100,count=1 // 为什么这里引用计数是1而不是0呢?

问题示例2:

#include<memory>
#include<cstdio>
#include<map>
using namespace std;
int main() {
    shared_ptr<int> ptr = make_shared<int>(100);
    printf("=%d,count=%ld\n", *ptr.get(), ptr.use_count());
    map<int, shared_ptr<int>> mp;
    mp.insert(pair<int, shared_ptr<int>>(1, ptr));
    mp.insert(pair<int, shared_ptr<int>>(2, ptr));
    printf("=%d,count=%ld\n", *ptr.get(), ptr.use_count());
    ptr.reset();
    printf("count=%ld\n", ptr.use_count());
    return 0;
}

输出:
=100,count=1
=100,count=3
count=0 //这里为什么是0而不是2呢? 一直理解的 reset()是引用计数减1.

解析

问题1:

ptr 还在,还有一个引用。

问题2:

reset 之后,ptr 的指向改变,引用计数已经不是原来指针的引用计数了。新指针是个 nullptr ,引用计数为 0 。原来的指针引用计数是 2 ,两个引用都在 map 里,已经无法通过 ptr 访问。

  • 对于问题 1 中的第三次输出,ptr 没有释放,因此还有 1 个引用计数占用,打印 1.
  • 对于问题 2 中的第三次输出,是 ptr 这个共享指针本身释放,而非资源释放,因此 ptr.use_count() 打印 0.

可以运行下面代码验证:

#include<memory>
#include<cstdio>
#include<map>
using namespace std;
int main() {
    shared_ptr<int> ptr = make_shared<int>(100);
    printf("=%d,count=%ld\n", *ptr.get(), ptr.use_count());
    map<int, shared_ptr<int>> mp;
    mp.insert(pair<int, shared_ptr<int>>(1, ptr));
    mp.insert(pair<int, shared_ptr<int>>(2, ptr));
    printf("=%d,count=%ld\n", *ptr.get(), ptr.use_count());
    ptr.reset();
    printf("count=%ld\n", ptr.use_count());
    printf("=%d,count=%ld\n", *mp[1].get(), mp[1].use_count());
    printf("=%d,count=%ld\n", *mp[2].get(), mp[2].use_count());
    return 0;
}

输出:

=100,count=1
=100,count=3
count=0
=100,count=2
=100,count=2

函数逻辑

你可以设想一下这个函数的逻辑

void reset() _NOEXCEPT
    {
        shared_ptr().swap(*this);
    }

第一步, 创造一个空shared_ptr对象,与原智能指针交换.交换后指向nullptr,引用为0;

第二步, 原始的指针成了右值, 在语句调用结束消灭, 随即, 原资源引用数减一, 如减为0, 自行消灭,否则继续留存.

 以上就是解析C语言中智能指针引用计数为什么不是0原理的详细内容,更多关于C语言智能指针引用计数的资料请关注脚本之家其它相关文章!

相关文章

  • C++实现学生选课系统

    C++实现学生选课系统

    这篇文章主要为大家详细介绍了C++实现学生选课系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • 用c语言实现一个电话薄(附完整代码)

    用c语言实现一个电话薄(附完整代码)

    大家好,本篇文章主要讲的是用c语言实现一个电话薄(附完整代码),感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2022-01-01
  • C++用read()和write()读写二进制文件的超详细教程

    C++用read()和write()读写二进制文件的超详细教程

    二进制的文件肉眼我们是读不懂的,如果通过二进制的读写操作就可以读懂,下面这篇文章主要给大家介绍了关于C++用read()和write()读写二进制文件的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • C/C++通过HTTP实现文件上传与下载的示例详解

    C/C++通过HTTP实现文件上传与下载的示例详解

    WinInet是 Microsoft Windows 操作系统中的一个 API 集,用于提供对 Internet 相关功能的支持,它包括了一系列的函数,使得 Windows 应用程序能够进行网络通信、处理 HTTP 请求、FTP 操作等,本文给大家介绍了C/C++通过HTTP实现文件上传与下载,需要的朋友可以参考下
    2023-12-12
  • C语言读取和存储bmp格式图片

    C语言读取和存储bmp格式图片

    这篇文章主要为大家详细介绍了C语言读取和存储bmp格式图片,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • C++中的异常实例详解

    C++中的异常实例详解

    异常处理是C++的一项语言机制,用于在程序中处理异常事件,下面这篇文章主要给大家介绍了关于C++中异常的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-02-02
  • C++使用cjson操作Json格式文件(创建、插入、解析、修改、删除)

    C++使用cjson操作Json格式文件(创建、插入、解析、修改、删除)

    本文主要介绍了C++使用cjson操作Json格式文件(创建、插入、解析、修改、删除),文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • OpenCV实现绕图片中任意角度旋转任意角度

    OpenCV实现绕图片中任意角度旋转任意角度

    这篇文章主要为大家详细介绍了在图片不被裁剪时,opencv如何实现绕图片中任意点旋转任意角度,文中的示例代码讲解详细,需要的可以参考一下
    2022-09-09
  • 数据结构与算法:单向链表实现与封装

    数据结构与算法:单向链表实现与封装

    今天小编就为大家分享一篇关于数据结构与算法:单向链表实现与封装,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • VC++ 获取系统时间的方法汇总

    VC++ 获取系统时间的方法汇总

    本文给大家汇总介绍了5种VC++中获取系统时间的方法,十分的简单实用,有需要的小伙伴可以参考下。
    2015-07-07

最新评论