当前位置: 首页 > news >正文

C++中的智能指针有哪些?分别解决的问题以及区别?

1.C++中的智能指针有4种,分别为:shared_ptr、unique_ptr、weak_ptr、auto_ptr,其中auto_ptr被C++11弃用。

2.使用智能指针的原因
申请的空间(即new出来的空间),在使用结束时,需要delete掉,否则会形成内存碎片。在程序运行期间,new出来的对象,在析构函数中delete掉,但是这种方法不能解决所有问题,因为有时候new发生在某个全局函数里面,该方法会给程序员造成精神负担。
此时,
智能指针就派上了用场。使用智能指针可以很大程度上避免这个问题,“因为智能指针就是一个类,当超出了类的作用域时,类会自动调用析构函数,析构函数会自动释放资源。”所以,智能指针的作用原理就是在函数结束时自动释放内存空间,避免了手动释放内存空间。

3.四种指针分别解决的问题以及各自特性如下:
(1)auto_ptr(C++98的方案,C++11已经弃用)采用所有权模式。

auto_ptr<string>p1(new string("Ireignedloneyasacloud."));
auto_ptr<string>p2;
p2=p1;//auto_ptr不会报错

此时不会报错,p2剥夺了p1的所有权,但是当程序运行时访问p1将会报错。所以auto_ptr的缺点是:存在潜在的内存崩溃问题。


唯一指针的诞生代替了auto_ptr

(2)unique_ptr(替换auto_ptr)
unique_ptr实现独占式拥有或严格拥有概念,保证同一时间内“只有一个智能指针”可以指向该对象。它对于避免资源泄露,例如,以new创建对象后因为发生异常而忘记调用delete时的情形“特别有用”。
采用所有权模式,和上面例子一样。

unique_ptr<string>p3(new string("Ireignedloneyasacloud."));
unique_ptr<string>p4;
p4=p3;//报错

编译器认为P4=P3非法,避免了p3不再指向有效数据的问题。因此,unique_ptr比auto_ptr更安全。
另外,
unique_ptr还有更聪明的地方:当程序试图将一个unique_ptr赋值给另一个时,如果源unique_ptr是个“临时右值”,编译器允许这么做;
如果源unique_ptr将存在一段时间,编译器将禁止这么做,比如:

unique_ptr<string>pu1(new string("helloworld"));unique_ptr<string>pu2;pu2 = pu1;//#1 not allowed
//----------------------------
unique_ptr<string>pu3;pu3 = unique_ptr<string>(new string("You"));//#2 allowed

其中#1留下悬挂的unique_ptr(pu1),这可能导致危害。
而#2不会留下悬挂的unique_ptr,因为它调用unique_ptr的构造函数,该构造函数创建的临时对象在其所有权让给pu3后就会被销毁。
这种随情况而已的行为表明,unique_ptr优于允许两种赋值的auto_ptr。
注意:如果确实想执行类似与#1的操作,要安全的重用这种指针,可给它赋新值。C++有一个标准库函数std::move(),让你能够将一个unique_ptr赋给另一个。
下面是一个使用前述demo()函数的例子,该函数返回一个unique_ptr对象:
使用move后,原来的指针仍转让所有权变成空指针,可以对其重新赋值。

unique_ptr<string>ps1,ps2;
ps1=demo("hello");
ps2=move(ps1);
ps1=demo("alexia");
cout<<*ps2<<*ps1<<endl;

(3)shared_ptr(非常好使)
shared_ptr实现共享式拥有概念。多个智能指针可以指向相同对象,该对象和其相关资源会在“最后一个引用被销毁”时候释放。从名字share就可以看出了资源可以被多个指针共享,它使用计数机制来表明资源被几个指针共享。可以通过成员函数use_count()来查看资源的所有者个数。除了可以通过new来构造,还可以通过传入auto_ptr,unique_ptr,weak_ptr来构造。当我们调用release()时,当前指针会释放资源所有权,计数减一。当计数等于0时,资源会被释放。shared_ptr是为了解决auto_ptr在对象所有权上的局限性(auto_ptr是独占的),在使用引用计数的机制上提供了可以共享所有权的智能指针。
成员函数:
use_count 返回引用计数的个数

unique 返回是否是独占所有权(use_count为1)

swap 交换两个shared_ptr对象(即交换所拥有的对象)

reset 放弃内部对象的所有权或拥有对象的变更,会引起原有对象的引用计数的减少

get 返回内部对象(指针),由于已经重载了()方法,因此和直接使用对象是一样的。如:shared_ptrsp(newint(1));sp与sp.get()是等价的

(4)weak_ptr
weak_ptr是一种不控制对象生命周期的智能指针,它指向一个shared_ptr管理的对象。进行该对象的内存管理的是那个强引用的shared_ptr。
weak_ptr只是提供了对管理对象的一个访问手段。weak_ptr设计的目的是为配合shared_ptr而引入的一种智能指针来协助shared_ptr工作,它只可以从一个shared_ptr或另一个weak_ptr对象构造,它的构造和析构不会引起引用记数的增加或减少。
weak_ptr是用来解决shared_ptr相互引用时的死锁问题,如果说两个shared_ptr相互引用,那么这两个指针的引用计数永远不可能下降为0,资源永远不会释放。
它是对对象的一种弱引用,不会增加对象的引用计数,和shared_ptr之间可以相互转化,shared_ptr可以直接赋值给它,它可以通过调用lock函数来获得shared_ptr

class B;
class A
{
public:shared_ptr<B>pb_;~A(){cout<<"Adelete\n";}
};
class B
{
public:shared_ptr<A>pa_;~B(){cout<<"Bdelete\n";}
};
void fun()
{shared_ptr<B>pb(new B());shared_ptr<A>pa(new A());pb->pa_=pa;pa->pb_=pb;cout<<pb.use_count()<<endl;cout<<pa.use_count()<<endl;
}
int main()
{fun();return 0;
}

可以看到fun函数中pa,pb之间互相引用,两个资源的引用计数为2,当要跳出函数时,智能指针pa,pb析构时两个资源引用计数会减一,但是两者引用计数还是为1,导致跳出函数时资源没有被释放(AB的析构函数没有被调用),如果把其中一个改为weak_ptr就可以了,我们把类A里面的shared_ptrpb_;改为weak_ptrpb;运行结果如下,这样的话,资源B的引用开始就只有1,当pb析构时,B的计数变为0,B得到释放,B释放的同时也会使A的计数减一,同时pa析构时使A的计数减一,那么A的计数为0,A得到释放。

注意:我们不能通过weak_ptr直接访问对象的方法,
比如:
B对象中有一个方法print(),我们不能这样访问,pa->pb_->print();
pb是一个weak_ptr,应该先把它转化为shared_ptr,如:
shared_ptr p=pa->pb_.lock();
p->print();

相关文章:

C++中的智能指针有哪些?分别解决的问题以及区别?

1.C中的智能指针有4种&#xff0c;分别为&#xff1a;shared_ptr、unique_ptr、weak_ptr、auto_ptr&#xff0c;其中auto_ptr被C11弃用。 2.使用智能指针的原因 申请的空间&#xff08;即new出来的空间&#xff09;&#xff0c;在使用结束时&#xff0c;需要delete掉&#xff0…...

通达信捉妖改良CCI指标公式,简洁巧妙

高端的食材&#xff0c;往往只需要简单的烹饪方式。好的指标也是一样&#xff0c;只需要简单处理&#xff0c;就可以实现不错的效果。捉妖改良CCI指标公式属于意外之喜&#xff0c;编写指标时写错了&#xff0c;研究后发现结果比原想法更好。 捉妖改良CCI指标公式利用了CCI&am…...

「Python 基础」面向对象编程

文章目录1. 面向对象编程类和实例访问限制继承和多态type()isinstance()dir()实例属性和类属性2. 面向对象高级编程\_\_slots\_\_property多重继承定制类枚举类元类1. 面向对象编程 Object Oriented Programming 简称 OOP&#xff0c;一种程序设计思想&#xff0c;以对象为程…...

【K3s】第23篇 一篇文章带你学习k3s私有镜像仓库配置

目录 1、私有镜像仓库配置 2、registries.yaml Mirrors Configs 1、私有镜像仓库配置 可以配置 Containerd 连接到私有镜像仓库,并使用它们在节点上拉取私有镜像。 启动时,K3s 会检查/etc/rancher/k3s/中是否存在registries.yaml文件,并指示 containerd 使...

Redis学习【12】之Redis 缓存

文章目录前言一 Jedis 简介二 使用 Jedis2.1 测试代码2.2 使用 JedisPool2.3 使用 JedisPooled2.4 连接 Sentinel 高可用集群2.5 连接分布式系统2.6 操作事务三 Spring Boot整合Redis3.1 创建工程3.2 定义 pom 文件3.3 完整代码3.4 总结四 高并发问题4.1 缓存穿透4.2 缓存击穿4…...

Bootargs 参数

bootargs 的参数有很多&#xff0c;而且随着 kernel 的发展会出现一些新的参数&#xff0c;使得设置会更加灵活多样1。除了我之前介绍的 root、console、earlyprintk 和 loglevel 之外&#xff0c;还有以下一些常用的参数&#xff1a;init: 用来指定内核启动后执行的第一个程序…...

Mybatis框架源码笔记(七)之Mybatis中类型转换模块(TypeHandler)解析

1、JDBC的基本操作回顾 这里使用伪代码概括一下流程: 对应数据库版本的驱动包自行下载加载驱动类 (Class.forName("com.mysql.cj.jdbc.Driver"))创建Connection连接: conn DriverManager.getConnection("jdbc:mysql://数据库IP:port/数据库名称?useUnico…...

论文阅读《Block-NeRF: Scalable Large Scene Neural View Synthesis》

论文地址&#xff1a;https://arxiv.org/pdf/2202.05263.pdf 复现源码&#xff1a;https://github.com/dvlab-research/BlockNeRFPytorch 概述 Block-NeRF是一种能够表示大规模环境的神经辐射场&#xff08;Neural Radiance Fields&#xff09;的变体&#xff0c;将 NeRF 扩展到…...

【Matlab】如何设置多个y轴

MTALAB提供了创建具有两个y轴的图&#xff0c;通过help yyaxis就能看到详细的使用方式。 但是如果要实现3个及以上y轴的图&#xff0c;就没有现成的公式使用了&#xff0c;如下图所示。 具体代码 % 数据准备 x10:0.01:10; y1sin(x1); x20:0.01:10; y2cos(x2); x30:0.01:10;…...

圆桌(满足客人空座需求,合理安排客人入座圆桌,准备最少的椅子)

CSDN周赛第30期第四题算法解析。 (本文获得CSDN质量评分【91】)【学习的细节是欢悦的历程】Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程》&#xff0c;不仅仅是基础那么简单…… 地址&#xff1a;https://lq…...

如何入门大数据?

我们首先了解一下大数据到底是什么~ 大数据开发做什么&#xff1f; 大数据开发分两类&#xff0c;编写Hadoop、Spark的应用程序和对大数据处理系统本身进行开发。 大数据开发工程师主要负责公司大数据平台的开发和维护、相关工具平台的架构设计与产品开发、网络日志大数据分…...

如何在Vite项目中使用Lint保证代码质量

通常,大型前端项目都是多人参与的,由于开发者的编码习惯和喜好都不尽相同,为了降低维护成本,提高代码质量,所以需要专门的工具来进行约束,并且可以配合一些自动化工具进行检查,这种专门的工具称为Lint,可能大家接触得最多就是ESLint。 对于实现自动化代码规范检查及修…...

Spark高手之路1—Spark简介

文章目录Spark 概述1. Spark 是什么2. Spark与Hadoop比较2.1 从时间节点上来看2.2 从功能上来看3. Spark Or Hadoop4. Spark4.1 速度快4.2 易用4.3 通用4.4 兼容5. Spark 核心模块5.1 Spark-Core 和 弹性分布式数据集(RDDs)5.2 Spark SQL5.3 Spark Streaming5.4 Spark MLlib5.5…...

社科院与杜兰大学金融管理硕士项目——人生没有太晚的开始,不要过早的放弃

经常听到有人问&#xff0c;“我都快40了&#xff0c;现在学车晚不晚呢”“现在考研晚不晚&#xff1f;”“学画画晚不晚&#xff1f;”提出这些疑问的人&#xff0c;往往存在拖延&#xff0c;想法只停留在想的阶段&#xff0c;从来不去行动。当看到周边行动起来的人开始享受成…...

Spatial-Temporal Graph ODE Networks for Traffic Flow Forecasting

Spatial-Temporal Graph ODE Networks for Traffic Flow Forecasting 摘要 交通流量的复杂性和长范围时空相关性是难点 经典现存的工作&#xff1a; 1.利用浅图神经网络&#xff08;shallow graph convolution networks&#xff09;和 时间提取模块去分别建模空间和时间依赖…...

IP协议+以太网协议

在计算机网络体系结构的五层协议中&#xff0c;第三层就是负责建立网络连接&#xff0c;同时为上层提供服务的一层&#xff0c;网络层协议主要负责两件事&#xff1a;即地址管理和路由选择&#xff0c;下面就网络层的重点协议做简单介绍~~ IP协议 网际协议IP是TCP/IP体系中两…...

可视化组件届的仙女‖蝴蝶结图、玫瑰环图、小提琴图

在上一篇内容中为大家介绍了几个堪称可视化组件届吴彦祖的高级可视化图表。既然帅哥有了&#xff0c;怎么能少得了美女呢&#xff1f;今天就为大家介绍几个可视化组件届的“美女姐姐”&#xff0c;说一句是组件届的刘亦菲不为过。蝴蝶结图蝴蝶结图因其形似蝴蝶结而得名&#xf…...

人的高级认知:位置感

你知道吗&#xff1f;人有个高级认知&#xff1a;位置感 位置感是啥&#xff1f;咋提高位置感&#xff1f; 趣讲大白话&#xff1a;知道自己几斤几两 【趣讲信息科技99期】 ******************************* 位置感 就是对自己所处环境和自身存在的领悟 属于人生智慧 来源于阅历…...

MATLAB——信号的采样与恢复

**题目&#xff1a;**已知一个连续时间信号 其中&#xff1a;f01HZ&#xff0c;取最高有限带宽频率fm5f0。分别显示原连续时间信号波形和 3种情况下抽样信号的波形。并画出它们的幅频特性曲线&#xff0c;并对采样后的信号进行恢复。 step1.绘制出采样信号 这部分相对简单…...

Docker Nginx 反向代理

最近在系统性梳理网关的知识&#xff0c;其中网关的的功能有一个是代理&#xff0c;正好咱们常用的Nginx也具备次功能&#xff0c;今天正好使用Nginx实现一下反向代理&#xff0c;与后面网关的代理做一个对比&#xff0c;因为我使用的docker安装的Nginx&#xff0c;与直接部署N…...

手把手教你实现书上的队列,进来试试?

一.队列的基本概念队列的定义队列&#xff08;queue&#xff09;是只允许在一端进行插入操作&#xff0c;而在另一端进行删除操作的线性表。队列是一种先进先出&#xff08;First In First Out&#xff09;的线性表&#xff0c;简称FIFO。允许插入的一端称为队尾&#xff0c;允…...

【springboot】springboot介绍

学习资料 SpringBoot 语雀 (yuque.com)【尚硅谷】SpringBoot2零基础入门教程&#xff08;spring boot2干货满满&#xff09;_哔哩哔哩_bilibiliSpringBoot2核心技术与响应式编程: SpringBoot2核心技术与响应式编程 (gitee.com) Spring 和Springboot 1、Spring能做什么 1.1…...

PMP项目管理项目整合管理

目录1 项目整合管理概述2 制定项目章程3 制定项目管理计划4 指导与管理项目工作5 管理项目知识6 监控项目工作7 实施整体变更控制8 结束项目或阶段1 项目整合管理概述 项目整合管理包括对隶属于项目管理过程组的各种过程和项目管理活动进行识别、定义、组合、统一和协调的各个…...

ADS中导入SPICE模型

这里写目录标题在官网中下载SPICE模型ADS中导入SPICE模型在官网中下载SPICE模型 英飞凌官网 ADS中导入SPICE模型 点击option&#xff0c;设置导入选项 然后点击ok 如果destination选择当前的workspace&#xff0c;那么导入完成之后如下&#xff1a; &#xff08;推荐使用…...

C++:异常

在学习异常之前&#xff0c;来简单总结一下传统的处理错误的方式&#xff1a; 1. 终止程序&#xff0c;如assert&#xff0c;缺陷&#xff1a;用户难以接受。如发生内存错误&#xff0c;除0错误时就会终止程序。 2. 返回错误码&#xff0c;缺陷&#xff1a;需要程序员自己去查找…...

3.初识Vue

目录 1 vue 浏览器调试工具 1.1 安装 1.2 配置 2 数据驱动视图与双向数据绑定 3 简单使用 3.1 下载 3.2 将信息渲染到DOM上 4 使用vue浏览器调试工具 5 vue指令 1 vue 浏览器调试工具 chrome可能是我浏览器的原因&#xff0c;装上用不了&#xff0c;我们使…...

【C语言复习】程序的编译与链接

程序的编译与链接写在前面程序的编译与链接编译的过程程序编译环境程序执行过程编译链接的过程预处理预处理符号#define条件编译写在前面 程序的编译与链接是C语言中非常重要的一节。关键点在于详解C语言的程序编译和链接、宏的定义和与函数的区别、条件编译等知识。 程序的编…...

Golang sql 事务如何进行分层

在写代码过程中遇到了需要使用gorm执行sql事务的情况&#xff0c;研究了一下各位大佬的实现方案&#xff0c;结合了自身遇到的问题&#xff0c;特此记录。 代码架构介绍 . ├── apis ├── config ├── internal │ ├── constant │ ├── controller │ ├──…...

linux系统openssh升级

linux系统openssh升级 说明 整个过程不需要卸载原先的openssl包和openssh的rpm包。本文的环境都是系统自带的openssh&#xff0c;没有经历过手动编译安装方式。如果之前有手动编译安装过openssh&#xff0c;请参照本文自行测试是否能成功。 如果严格参照本文操作&#xff0c;保…...

力扣-求关注者的数量

大家好&#xff0c;我是空空star&#xff0c;本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目&#xff1a;1729. 求关注者的数量二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.正确…...

做公司门户网站的重点/自学seo能找到工作吗

java.nio包提供了Buffer API&#xff0c;使得Java程序可以直接控制和运用缓冲区。 java.nio public abstract class Buffer extends Object Buffer接口 缓冲区是包在一个对象内的基本数据元素的数组。Buffer类相比简单数组的优点是它将关于数据的数据内容和信息包含在一个单一…...

广东省建设网站/做百度推广

摘 要&#xff1a;本文阐述了逻辑与计算、计算机的起源、程序设计之间的相互关系&#xff0c;并在一阶逻辑的基础上&#xff0c;以LISP、PROLOG等为例&#xff0c;给出了逻辑在程序设计语言和逻辑程序设计中的应用&#xff0c;以此说明计算机科学是逻辑的超大规模应用。关键词&…...

天河手机网站建设/又一病毒来了比新冠可怕

网站制作一年350元&#xff0c;五站合一&#xff0c;快速建站 &#xff0c;www.sxjcwzjs.com,只需进入网站右上角注册快速建站即可(需要电脑登录注册)&#xff0c;需要联系我吧&#xff01;电话&#xff1a;13752214574&#xff0c;微信号&#xff1a;m1078582894个人如果会敲代…...

响应式网站和普通网站/如何做好百度推广

http://blog.csdn.net/yihaiyiren/article/details/17220927转载于:https://www.cnblogs.com/xiyushimei/p/8561392.html...

没有网站怎么做cpa/厦门seo外包平台

运行后报如下错误&#xff1a; 经分析检查 所有的mapper映射并没有cn.**的上下文类。。。。。反复清理了本地缓存后&#xff0c;然没有什么效果。想了好几天&#xff0c;忽然顿悟&#xff0c;最近在反复部署项目&#xff0c;是否是远程redis缓存导致的问题&#xff1f; 于是检…...

重装的系统没有wordpress/招聘seo专员

1.前提 电脑安装好Git需要有个已经注册的GitHub帐号 2.在IDEA中设置Git 2.1 确保IDEA安装Git GitHub插件 2.2 在IDEA中设置Git&#xff0c;在File–>Setting->Version Control–>Git–>Path to Git executable选择你的git安装后的git.exe文件&#xff0c;然后点…...