c++智能指针(4)-- shared_ptr

概述

场景一:   希望指向多个指针管理一片空间

unique_ptr它是不允许两个智能指针管理一片空间的,所以其禁止直接拷贝和赋值(转化为右值可以)。

auto_ptr虽然其允许我们多个智能指针管理一片空间,但是这样的操作对于auto_ptr来说是不安全的,因为一个智能指针释放空间时,是不管别的指针的。

但是,我们有时候是希望,使用多个指针来指向同一片空间的,这样unique_ptr无法实现,auto_ptr又不安全,所以c++11又增加了shared_ptr,它是允许我们使用多个智能指针管理一片空间的。

场景二:  作为容器的类型

前面说到unique_ptr和auto_ptr作为容器的类型的时候,是无法满足容器的特性的(就是两个元素之间赋值),但是shared_ptr是支持的。

 

shared_ptr原理 

智能指针中使用引用计数的方式来判断是否需要释放智能指针指向的动态的空间。

shared_ptr内部使用引用计数的方式,每一片空间都有一个引用计数,每有一个指针指向这片空间,那么其引用计数就会加1,有指针不指向它了,其引用计数就会减1。 


当智能指针管理的空间的引用计数为0的时候,就会释放这块内存。

所以使用shared_ptr指向同一片空间,是不会出现一个释放影响别的指针使用的,因为一个指针不使用,其只会影响引用计数,只有当智能指针释放的时候,空间的引用计数也减为0了,那么就会释放这块空间。(也就是只有一个智能指针管理这块空间时,当智能指针释放,这块空间也就释放了)

 

注意事项(适用于所有智能指针) 

我们不能随便将一块地址让智能指针进行管理,只能将动态开辟的空间让它去管理。

 比如:  int a = 10;

           auto_ptr<int> p1(&a);  // error;


千万注意上面这样的代码,因为我们智能指针的析构函数是使用delete来释放空间的,也就是说其管理的应该是动态开辟的空间,如果像上面那样写,会导致delete释放非堆内存,这显然不对。

 

1. 定义shared_ptr的对象 

  • unique_ptr<类型>  p1(new 空间);  // 类型:  智能指针指向的类型,空间:智能指针管理的空间 
  • std::shared_ptr<int> p1;
    std::shared_ptr<int> p1(NULL);  // 创建指向空的智能指针,注意,此时其引用计数为                                                             0(因为没有指向空间)
  • std::shared_ptr<int> p1(new int());  //  p1直系那个一片空间,引用计数+1
  • 使用auto_ptr,unique_ptr,shared_ptr的临时对象初始化
    std::shared_ptr<int> p1(std::unique_ptr<int> (new int)); // 执行完这行unique_ptr的指针                                                                                             就释放了
    std::shared_ptr<int> p1(std::shared_ptr<int> (new int));
    std::shared_ptr<int> p1(std::auto_ptr<int> (new int));
  •     int a = new int();
        std::shared_ptr<int> p1(&a);

 

2. 多个指针指向同一块空间 

  • 拷贝构造
    std::shared_ptr<int> p1(new int());
    std::shared_ptr<int> p2(p1); 
     
  • 赋值 -- 所以其可以作为容器的类型,其更加符合容器的要求(一个元素可以赋值给另外一个元素)
    std::shared_ptr<int> p1(new int());
    std::shared_ptr<int> p2;
    p2 = p1;


例子:  

std::shared_ptr<int> p1(new int(10));  // p1指向空间,引用计数+1(为1)
{
    std::shared_ptr<int> p2;
    p2 = p1;   // 指针p2和p1指向了同一片空间(引用计数加1(为2)),在大括号结束之后,p2被                           释放,引用计数减1(为1)。
}
std::cout << *p1 << std::endl; // 由于p2释放后引用计数为1,所以空间没有释放,所以此时                                                      访问空间数据没有问题。
当然,当p1析构,那么引用计数就变成0了,那么就释放掉此空间。

 

3. shared_ptr的函数 

1)use_count()函数 

  • long use_count();

我们前面说到,共享指针基于引用计数来实现多个指针管理一片空间的,那我们如何知道当前的指针指向的空间被多少的指针指向。

我们可以使用use_count(),这个函数返回当前指针指向空间的引用计数是多少。 

代码: 
int main(void) {std::shared_ptr<int> p1(new int(10));{std::shared_ptr<int> p2(p1);std::cout << p2.use_count() << std::endl;  // 输出2}std::cout << p1.use_count() << std::endl; // 输出1std::cin.get();
}

 

2) unique()函数 

  • bool unique(); // 用来判断,当前指针指向其管理空间的是否只有它(引用计数是否为1),如果是返回true,如果不是返回false。
代码: 
std::shared_ptr<int> p1(new int(10));  
if (p1.unique()) {   // 返回truestd::cout << "引用计数为1" << std::endl;  // 正常输出
}

 

3)swap(),get(),release()函数 

 

  • T* get(p); // 返回智能指针指向的空间地址
  • void p.reset(地址); // 重新设置智能指针指向的空间地址
  • T* release(p); // 将管理空间的权限重到我们手中

当然这些函数和auto_ptr的用法一样,那里我们进行了详细的描述。 

 

4. 内置类型element_type

表示当前智能指针指向的数据的类型,我们在使用智能指针数据的时候,可以直接使用此类型来统一表示,并不用去关心其具体指向什么类型。 


std::shared_ptr<int>::element_type t = 10;

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/233.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker Volume (存储卷)

什么是存储卷? 存储卷就是将宿主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立绑定关系。这就意味着&#xff0c;当我们在容器中的这个目录下写入数据时&#xff0c;容器会将其内容直接写入到宿主机上与此容器建立了绑定关系的目录。在宿主机上…

选课成绩管理系统

文章目录 员工管理系统一、项目演示二、项目介绍三、系统部分功能截图四、部分代码展示五、底部获取项目&#xff08;9.9&#xffe5;&#xff09; 员工管理系统 一、项目演示 课程管理系统 二、项目介绍 基于springbootvue的前后端分离选课成绩管理系统 该系统可做课程管理…

rpi-ws281x库测试介绍

彩色RGB灯测试-rpi-ws281x库使用 1 rpi-ws281x库介绍 rpi-ws281x 是一个针对 Raspberry Pi 的库&#xff0c;用于控制WS281X 系列 LED 灯带&#xff08;例如 WS2812B&#xff09;的颜色和亮度。它提供了一个 Python 接口&#xff0c;让你可以轻松地通过 Raspberry Pi 控制这些…

基础算法之二分算法

前言 本次博客&#xff0c;将要介绍二分算法的基本原理以及如何使用&#xff0c;深入浅出 二分可以针对整型以及浮点型接下来对其讲解希望对小白有所帮助吧 整型的二分法 一般要在一个数组中猜出一个数是否存在我们可以遍历一遍整个数组&#xff0c;判断是否存在&#xff0…

使用Windows11自带的WSL安装Ubuntu Linux系统教程

WSL介绍 WSL全称Windows Subsystem for Linux&#xff0c;它是Windows10带来的新特性&#xff0c;用于Windows系统上的Linux子系统。也就是说&#xff0c;可以在Windows系统中获取Linux系统&#xff0c;这个过程无需通过虚拟机&#xff0c;而是直连计算机硬件。 简而言之&#…

Linux--进程间的通信-命名管道

前文&#xff1a; Linux–进程间的通信-匿名管道 Linux–进程间的通信–进程池 命名管道的概念 命名管道是一种进程间通信&#xff08;IPC&#xff09;机制&#xff0c;运行不同进程之间进行可靠的、单向或双向的数据通信。 特点和作用&#xff1a; 跨平台性&#xff1a;在W…

ResNet最新变体!性能反超Transformer,模型准确率达98.42%

目前ResNet&#xff08;残差网络&#xff09;有两大主流创新思路&#xff1a;一是与其他技术或模型结合&#xff0c;比如前文讲到的ResNetTransformer&#xff1b;二是在原始设计的基础上进行改进。 尽管ResNet通过残差学习有效改善了深层网络的训练和性能&#xff0c;但同时它…

【LeetCode热题100】【堆】数据流的中位数

题目链接&#xff1a;295. 数据流的中位数 - 力扣&#xff08;LeetCode&#xff09; 不停插入元素要求找到每个状态的中位数&#xff0c;用两个堆&#xff0c;把中位数左边的数记为left&#xff0c;右边的数记为right&#xff0c;一个大顶堆记录小于等于中位数的left&#xff…

永磁同步电机无感FOC(扩展卡尔曼滤波EKF位置观测控制)

文章目录 1、前言2、扩展卡尔曼滤波器原理2.1 预测阶段&#xff08;时间更新阶段&#xff09;2.2 校正阶段&#xff08;状态更新阶段&#xff09; 3、永磁同步电机EKF的模型4、永磁同步电机EKF的无位置状态观测仿真4.1 核心模块&#xff08;在滑膜、龙伯格、磁链等观测器基础上…

数据库-Redis(10)

目录 46.Redis内存淘汰算法有哪些? 47.Redis内存用完了会发生什么? 48.Redis如何做内存优化?

三角洲期刊投稿发表论文

《三角洲》杂志是由国家新闻出版总署批准&#xff0c;南通市委宣传部主管&#xff0c;南通日报社、南通市文学艺术界联合会主办的正规文学类期刊。适用于发表高品质文学学术作品&#xff0c;科研机构的专家学者以及高等院校的师生等具有原创性的学术理论、工作实践、科研成果和…

openEuler-23.03下载

下载地址&#xff1a;openEuler下载 | 欧拉系统ISO镜像 | openEuler社区官网 下载版本&#xff1a;openEuler-23.03-x86_64-dvd.iso

H264标准协议基础3

参考博文 上一篇H264标准协议基础2 1.解码视频帧的poc计算 2.残差4x4 矩阵中的trailingones & numcoeff 2.1查表 trailingones 表达出尾部one(1,-1)系数的个数,按照zigzag扫描出(1,-1)个数,trailingones的最大为3; numcoeff 表达非零值系数的个数,最多为16个…

Linux shell 脚本基础与部署SpringCloud实战

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

供应链投毒预警 | 开源供应链投毒202403月报发布啦!(含投毒案例分析)

悬镜供应链安全情报中心通过持续监测全网主流开源软件仓库&#xff0c;结合程序动静态分析方式对潜在风险的开源组件包进行动态跟踪和捕获&#xff0c;能够第一时间捕获开源组件仓库中的恶意投毒攻击。在2024年3月份&#xff0c;悬镜供应链安全情报中心在NPM官方仓库&#xff0…

Flattened Butterfly 扁平蝶形拓扑

Flattened Butterfly 扁平蝶形拓扑 1. 传统蝶形网络 Butterfly Topology2. 扁平蝶形拓扑 Flattened Butterfly3.On-Chip Flattened Butterfly 扁平蝶形拓扑应用于片上网络 Flattened Butterfly 扁平蝶形拓扑 扁平蝶形拓扑是一种经济高效的拓扑&#xff0c;适用于高基数路由器…

OpenHarmony南向开发案例:【智能照相机】

样例简介 本Demo是基于Hi3516开发板&#xff0c;使用OpenHarmony3.0-LTS开发的应用。通过获取摄像头数据&#xff0c;实现预览拍照以及路视频等功能。并且通过后台AI服务识别唤醒词来进行语音控制拍照及录制视频。 应用运行效果图&#xff1a; 此为相机的预览界面。 样例原理…

OpenHarmony多媒体-ohos_videocompressor

介绍 videoCompressor是一款ohos高性能视频压缩器。 目前实现的能力&#xff1a; 支持视频压缩 使用本工程 有两种方式可以下载本工程&#xff1a; 开发者如果想要使用本工程,可以使用git命令 git clone https://gitee.com/openharmony-sig/ohos_videocompressor.git --…

推荐一款免费虚拟主机,小编亲测好用!

虚拟主机是一种将物理服务器分割成多个虚拟服务器的技术&#xff0c;每个虚拟服务器都具有独立的操作系统和资源。相较于独立服务器&#xff0c;虚拟主机具有较低的成本和维护难度&#xff0c;因此受到了许多个人和小型企业的青睐。本文将为大家推荐一款免费且性能优秀的虚拟主…

鸿蒙入门05-真机运行“遥遥领先”

如果你有一台真的 "遥遥领先"那么是可以直接在手机上真机运行你的项目的我们也来尝试一下运行 一、手机设置开发者模式 打开手机设置 打开手机设置界面 向下滑动到关于手机位置 快速连续点击版本号位置 下图所示位置快速连续点击 打开 3 - 5 次即可 会提示您已经进…