shared_ptr智能指针的使用

2023-11-14

一、shared_ptr简单说明

如果一个实例指针被多个对象使用,而调用者不知道该什么时候释放该实例。那么可以使用shared_ptr来"托管"这个实例指针,当使用它的对象都被释放掉了,这个实例可以自动被释放。

可能有点绕,简单地说,就是类A的实例指针pA,被传入对象B、C、D中使用,那么当B、C、D被释放时,也就是不再持有pA时,pA指向的实例被自动释放。

shared_ptr的使用与普通指针类似。不过其内部有引用计数,若被引用次数=0,或者shared_ptr被销毁,那么其托管的对象就会被释放。

1.shared_ptr初始化:

class Buffer
{
    //....
};

shared_ptr<Buffer> pSharedBuffer = make_shared<Buffer>();

make_shared()内部自动实例化Buffer对象。

禁止:shared_ptr不可多次引用同一对象。

int* p = new Buffer();
shared_ptr<int> sp1(p);
shared_ptr<int> sp2(p);  // error

2.增加引用计数

shared_ptr<Buffer> xxx = pSharedBuffer;

此时xxx与pSharedBuffer指向同一个对象,且共用一个引用计数,为2,表示被引用2次。

3.reset()函数

pSharedBuffer.reset();

解除指针的托管,相当于pSharedBuffer引用计数=0,此时Buffer实例被释放。

4.若要使用shared_ptr封装this指针,则:

#include <memory>
class Test : public enable_shared_from_this<Test>
{
public:
    Test() {}
    ~Test() {}
    
    shared_ptr<Test> getThis()
    {
        return shared_from_this();
    }
};

int main()
{
    shared_ptr<Test> sp(new Test());
    shared_ptr<Test> temp = sp->getThis();
    return 0;
}

二、编写测试代码

Buffer类:

class Buffer
{
public:
    Buffer()
    {
        cout << "Buffer()" << endl;
    }

    ~Buffer()
    {
        cout << "~Buffer()" << endl;
    }

    void getPtr()
    {
        cout << "get buffer ptr" << endl;
    }
};

User类:

class User
{
public:
    void setBuffer(shared_ptr<Buffer> pBuf)
    {
        pBuffer = pBuf;
    }

    void useBuffer()
    {
        pBuffer->getPtr();
    }

private:
    shared_ptr<Buffer> pBuffer;
};

main():

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    shared_ptr<Buffer> pSharedBuffer = make_shared<Buffer>();
    cout << "use count:" << pSharedBuffer.use_count() << endl;

    User* user1 = new User();
    user1->setBuffer(pSharedBuffer);
    cout << "use count:" << pSharedBuffer.use_count() << endl;
    user1->useBuffer();

    User* user2 = new User();
    user2->setBuffer(pSharedBuffer);
    cout << "use count:" << pSharedBuffer.use_count() << endl;
    user2->useBuffer();

    delete user1;
    cout << "use count:" << pSharedBuffer.use_count() << endl;

    delete user2;
    cout << "use count:" << pSharedBuffer.use_count() << endl;

    pSharedBuffer.reset();
    cout << "use count:" << pSharedBuffer.use_count() << endl;

    return a.exec();
}

运行结果:
在这里插入图片描述



若对你有帮助,欢迎点赞、收藏、评论,你的支持就是我的最大动力!!!

同时,阿超为大家准备了丰富的学习资料,欢迎关注公众号“超哥学编程”,即可领取。

本文涉及工程代码,公众号回复:06shared_ptr,即可下载。

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

shared_ptr智能指针的使用 的相关文章

随机推荐

  • flyway出现org.flywaydb.core.api.FlywayException: Validate failed:问题解决办法

    在idea中找到数据库 如下图所示 双击flyway出现执行 mvn flyway migrate 历史记录 把最新执行看到执行失败的那条记录删掉 并提交 然后重新运行mvn flyway migrate 命令即可成功
  • Mybatis---配置文件元素属性详解

    Mybatis配置文件详解 Mybatis配置文件层次结构层次结构顺序不能改变否则会报错 Properties子元素 设置settings 类型别名typeAliases 系统定义别名 自定义别名 typeHandler类型处理器 系统定义
  • nginx代理yum

    适用场景 有多台服务器 但是只有1台服务器可以出公网 此时即可使用如下方式 进行yum代理 解决内网服务器不能yum的尴尬 一 首先需要把 etc yum repos d下的文件备份到bak 然后留一个CentOS Base repo 编辑
  • 农夫过河——python类穷举法实现

    一个农夫在河的西岸带了一匹狼 一只羊和一棵白菜 他需要把这三样东西用船带到河的东岸 然而 这艘船只能容下农夫本人和另外一样东西 如果农夫不在场的话 狼会吃掉羊 羊也会吃掉白菜 w 1 2 3 西岸初始状态 0代表没有 1代表白菜 2代表羊
  • 编译、安装和使用FANN库(环境部署)

    编译 安装和使用FANN库 环境部署 下载FANN的源代码 Github上面是官方的仓库 地址是libfann fann 它大概已经有两年时间是2 2 0版本 目前还看不到有什么活跃的提交 克隆主分支 git clone depth 1 h
  • 十个常见的Git面试题及详细解答

    Git是目前最流行的分布式版本控制系统之一 广泛应用于软件开发中 在Git面试中 面试官通常会提问一些与Git相关的问题 以评估候选人的版本控制技能和了解他们对Git的理解 本文将介绍十个常见的Git面试题 并提供详细的解答 帮助读者更好地
  • JVM 讲解

    目录 1 JVM 运行流程 2 JVM 基本组成 重要 2 1 堆 线程共享 2 2 Java 虚拟机栈 线程私有 2 3 本地方法栈 线程私有 2 4 程序计数器 线程私有 2 5 方法区 线程共享 3 OOM 4 JVM 垃圾回收算法
  • Airflow Trigger DAG with config

    1 rest api to trigger dag POST api experimental dags
  • 基于51单片机的霍尔自行车里程测速仪(含Keil程序和Proteus文件)

    系统概述 系统使用的模块有AT89C51单片机 LCD1602显示屏 霍尔测速模块 本设计采用51单片机为核心控制 使用LCD1602显示采集到的速度 霍尔测速模块进行测速 测速的原理是通过磁感应原理检测开关变化量 通过检测两个开关量的时间
  • 【javascript】闭包

    通过定时器从第一个元素开始往后 每隔一秒输出arr数组中的一个元素 但是运行过后 我们却会发现结果是每隔一秒输出一个 undefined 这是为什么呢 setTimeout 函数与for循环在调用时会产生两个独立执行上下文环境 当setTi
  • grep查找进程时,忽略grep进程本身

    ps ef grep 进程名 grep v grep grep v grep即去除结果中含有grep的进程 但是要注意如果你的进程名中本身含有grep也会被忽略 这时就需要更细致的规则 例如去除条件里加上一个空格 ps ef grep 进程
  • Matlab笔记

    1 创建矩阵 gt gt a 1 2 3 4 5 8 1 2 8 1 2 8可以是1起始值 公差 结束值 也可以是1 2 7 a 1 2 3 4 5 6 7 8 1 3 5 7 1 2 特殊矩阵 名称 函数 说明 单位矩阵 eye m n
  • leetcode链表刷题:删除中间节点

    题目如下所示 这道题正如评论区所言 最大的难度就是读懂题目本身 这道题的意思是 有一个链表 题目给了我这个链表上除了第一个和最后一个节点以外的一个中间节点 然后我要把这个中间节点给删掉 也就是说 我们能够进行操作的 是一个链表上的一个节点
  • leetcode 10. 正则表达式匹配

    2023 9 20 感觉是目前做过dp题里最难的一题了 本题首要的就是需要理解题意 翻了评论区我才发现之前一直理解的题意是错的 我原来理解的 匹配0次 是指 直接消失 不会影响到前面的字符 但是 和前一个字符其实是连体的 所以说 如果匹配0
  • 网络空间安全导论

    感谢戴银涛老师的指导 笔记时间有点儿久了 整理的时候一些图丢了 不过问题不大 网络空间安全导论 目录 1 信息安全概述 从网络信息系统的发展概述 从系统分析方法看信息与信息安全的关系 从信息安全技术史角度理解网络安全相关概念 网络信息系统安
  • 深入理解 TCP 协议:从原理到实战

    小册介绍 TCP 协议是我一直很想写的一个主题 因为 TCP 学起来实在是太痛苦了 刚参加工作时 TCP 协议一直是一个心头痛 知道皮毛 但是始终无法深入 在阅读了大量相关的书籍 做了很多网络编程方面的工作以后觉得掌握的过程太过曲折 这本小
  • 【前端代码实例】使用HTML5+CSS3+JavaScript制作一个响应式的后台管理系统~带侧边导航栏仪表盘功能

    bilibili在线视频演示地址 前端代码实例 使用HTML5 CSS3 JavaScript制作一个响应式的后台管理系统 带侧边导航栏仪表盘功能 效果图 简化版代码
  • C++学习(三十四)stdlib与cstdlib

    C语言中是有 include
  • 简单xml的使用以及xml的解析dom4j和jaxp

    1 xml的简介 w3c组织发布 extensible markup Language 可扩展标记型语言 也是使用标签操作 可扩展 html里面的标签是固定 每个标签都有特定的含义 xml标签可以自己定义 可以写中文的标签 用途 显示数据
  • shared_ptr智能指针的使用

    一 shared ptr简单说明 如果一个实例指针被多个对象使用 而调用者不知道该什么时候释放该实例 那么可以使用shared ptr来 托管 这个实例指针 当使用它的对象都被释放掉了 这个实例可以自动被释放 可能有点绕 简单地说 就是类A