智能指针管理“newed对象”

为什么要有智能指针?

指针智能是管理管理动态内存分配对象的一种机制。它提供了自动管理内存,避免常见内存泄漏和悬空指针。

对于上述Func函数的操作,一不小心就会产生很多问题。

  • p1 new时候抛异常 什么都不做
  • p2 new时候抛异常 p1需要被清理
  • div除0错误 p1 p2 都需要清理

上述代码我们也实现了delete,但是却有没被调用的风险。

资源没有被回收,就会导致内存泄漏,内存越用越多,如操作系统会卡死。

自动管理资源——智能指针

RAII(Resource Acquisition Is Initialization)是一种利用对象生命周期来控制程序资源
        在对象构造时获取资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源。借此,我们实际上把管理一份资源的责任托管给了一个对象。这种做法有两大好处:

  • 不需要显式地释放资源。
  • 采用这种方式,对象所需的资源在其生命期内始终保持有效

指针智能就是针对RAII思想设计的一种管理资源的方法;


智能指针的使用

1)利用对象生命周期管理

智能指针的基本使用思路。将对象通过指针交给一个类,类在调用的时候,构造完成初始化,析构完成自动清理资源。


解决上述问题

创建对象sp1 sp2时,会调用构造函数,将new int 构造类中的指针。在sp1 sp2的生命周期结束时(栈帧的销毁)会调用对象的析构函数 ,将动态开辟的内存释放掉

new sp1异常 什么都不做 没有任何构造

new sp2 异常栈帧会跳转到catch 局部变量sp1会被销毁,调用析构

div()函数出异常 局部变量sp1和sp2的栈帧都要被销毁,自动调用析构函数

上述操作就是将一个对象托管给另一个对象管理资源。就是RAII的思想 


*和->

为了让智能指针能够像指针一样操作。我们将智能指针进行操作符重载。*(解引用)和&(取地址)。


浅拷贝问题

利用上述的指针管理资源。不适合拷贝对象。

类中对于拷贝操作默认是浅拷贝,就是将对象资源按照字节一个个拷贝过去。

对于本题中,new开辟一块空间,将空间的地址交给智能指针构造出sp1,由sp1管理资源。

而在第二步拷贝赋值中,将sp1的地址一个字节一个字节拷贝给sp2,因此二者指向同一块空间。

在对象生命周期结束时,会自动调用析构函数。sp1和sp2指向同一块空间。一块空间delete俩次,所以会产生错误。

怎么解决?

这里就从历史的角度谈谈


auto_ptr

在C++98中,提出管理权限转移的思想。

假定都是sp1做为要被覆盖的对象

  • 在拷贝构造和赋值时,将被赋值对象的资源转移到自身。
  • 在拷贝构造时-----sp2指针的地址转为空
  • 在赋值时------需要检查是否自己赋值自己!然后需要释放sp1的内存,将sp2的内存转移到sp1上

将sp2的指针悬空

由于资源管理权限被转移,指针存在悬空。

unique_ptr

在C++98和C++11之间产生了非官方库 boost

unique_ptr

简单粗暴----防止拷贝

在成员函数中,如果不写拷贝构造函数和赋值运算符,编译器就会自动生成默认函数。如果我们显示的实现,而不再赋值上操作。如果只是声明,不写实现,那么有可能在类外被实现。

因此要在类内实现声明,并且声明为私有

在C++11中,delete关键字禁止生成默认函数


三 

shared_ptr

shared_ptr 其实就是对资源做引用计数——当引用计数为 0 的时候,自动释放资源。

比如我们有俩个对象同时指向同一块空间(sp1,sp2)。如果sp1被销毁了,就会什么也不做。然后空间配套的引用计数就会从2减到1。如果当sp2也要被释放时,引用计数从1减到0,此时计数为0,就要释放这块空间。

简单的来说shared_ptr包含俩部分

  • 一个指向堆上创建的裸指针
  • 一个指向内部隐藏的、共享的管理对象 count代表被多少对象引用共享了,也就是引用对象。

计数器设为全局吗?

在C++中用全局变量要非常谨慎。

如果将计数器设为全局,那么计数器就属于全部的类,该类的任何一个对象的增加或减少,都会影响计数器。因此需要对每一块资源分配一个计数器。

  • 构造:为_pcount开空间
  • release():减计数不为0不操作,计数为0时,删除空间
  • 赋值:检查自己赋值自己,释放旧空间 更新_pcount 
  • 拷贝构造:拷贝地址和_pcount ,更新_pcount
  • 基本指针操作

循环引用的解决

shared_ptr指针还存在循环引用的问题,再下一篇文章中将作为重点探讨,同时介绍weak_ptr。

总结


1. 尽量使用智能指针管理资源申请与释放,减少人为new和delete误操作和考虑不周的问题。

2.RAII思想就是利用变量生命周期管理资源。

点我gitee提取代码

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

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

相关文章

深入理解JVM虚拟机第三十篇:详解JVM当中栈帧的一些附加信息以及虚拟机栈的5个面试题

😉😉 欢迎加入我们的学习交流群呀: ✅✅1:这是孙哥suns给大家的福利! ✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 🥭🥭3:QQ群:583783824 📚📚 工作微信:BigTreeJava 拉你进微信群,免费领取! 🍎🍎4:本文章…

如何在Ubuntu的Linux系统上搭建nacos集群

官方给出的集群部署架构图 集群部署说明 (nacos.io)3个或3个以上nacos节点才能构成集群当前示例中包含3个nacos节点,同时一个负载均衡器代理3个nacos,本示例中负载均衡器可使用的是nginx 准备并安装好正常运行的nginx,本示例略准备并安装好正…

Redis权限管理体系(一):客户端名及用户名

在Redis6之前的版本中,因安全认证的主要方式是使用Redis实例的密码进行基础控制,而无法按照不同的应用来源配置不同账号以及更细粒度的操作权限控制来管理。本文先从client list中的信息入手,逐步了解Redis的客户端名设置、用户设置及权限控制…

【Monitor, Maintenance Operation, Script code/prgramme】

Summary of M,M&O,Program JD) Monitor & M&O Symbio信必优) Job chance/opportunities on Dec 12th, 20231.1) Content 招聘JD job description:1.2) suggestions from Ms Liang/Winnie on Wechat app1.3) Java微服务是什么?1.3.1) [URL Java 微服务](…

京微齐力:基于H7的平衡控制系统(一、姿态解析)

目录 前言一、关于平衡控制系统二、实验效果三、硬件选择1、H7P20N0L176-M2H12、MPU6050 四、理论简述五、程序设计1、Cordic算法2、MPU6050采集数据3、fir&iir滤波4、姿态解算 六、资源消耗&工程获取七、总结 前言 很久之前,就想用纯FPGA做一套控制系统。可…

C++二维数组(2)

图形相似度 题目描述: 给出两幅相同大小的黑白图像(用0-1矩阵)表示,求它们的相似度。 说明:若两幅图像在相同位置上的像素点颜色相同,则称它们在该位置具有相同的像素点。 两幅图像的相似度定义为相同像素…

橘子学K8S01之容器中所谓的隔离

我们一直都在说容器就是一个沙盒,沙盒技术顾名思义就是像一个集装箱一样,把应用(服务,进程之类的)装起来的技术,这样每个进程在自己的沙盒中和其他的沙盒隔离开来,每个沙盒之间存在一个边界使得他们互不干扰&#xff0…

鸿鹄云商:Java商城引领商业模式的潮流,免费搭建多种商城模式

java SpringCloud版本b2b2c鸿鹄云商平台全套解决方案 使用技术: Spring CloudSpring BootMybatis微服务服务监控可视化运营 B2B2C平台: 平台管理端(包含自营) 商家平台端(多商户入驻) PC买家端、手机wap/公众号买家端 微服务(30个通用…

用23种设计模式打造一个cocos creator的游戏框架----(十六)亨元模式

1、模式标准 模式名称:亨元模式 模式分类:结构型 模式意图:运用共享技术有效地支持大量细粒度的对象 结构图: 适用于: 1、一个应用程序使用了大量的对象. 2、完全由于使用大量的对象,造成很大的存储开…

铭飞CMS list 接口 SQL注入漏洞复现

0x01 产品简介 铭飞CMS是一款基于java开发的一套轻量级开源内容管理系统,铭飞CMS简洁、安全、开源、免费,可运行在Linux、Windows、MacOSX、Solaris等各种平台上,专注为公司企业、个人站长快速建站提供解决方案 0x02 漏洞概述 铭飞CMS在5.2.10版本以前list 接口处存在sql注入…

什么是CAS(比较并交换-乐观锁机制-锁自旋)

什么是 CAS(比较并交换-乐观锁机制-锁自旋) 概念及特性 CAS(Compare And Swap/Set)比较并交换,CAS 算法的过程是这样:它包含 3 个参数CAS(V,E,N)。V 表示要更新的变量(内存值),E 表示预期值(旧…

嵌入式开发板qt gdb调试

1) 启动 gdbserver ssh 或者 telnet 登陆扬创平板 192.168.0.253, 进入命令行执行如下: chmod 777 /home/HelloWorld (2) 打 开 QTcreator->Debug->StartDebugging->Attach to Running Debug Server 进行…

Nginx-nginx-1.18.0编译时默认包含哪些模块?nginx-1.18.0有哪些模块和配置语句,各有什么作用?

目录 01-如何查看 Nginx-nginx-1.18.0编译时默认包含哪些模块?02-如何查看Nginx有哪些自己可以手动设置添加或不添加的模块03-各配置语句和模块功能简介03-001:--pid-pathPATH03-002:--lock-pathPATH 03-003:select_module 03-004…

[湖湘杯 2021 final]MultistaeAgency

题目是给了源码,我们先来看web的main.go package mainimport ("bytes""crypto/md5""encoding/json""fmt""io""io/ioutil""log""math/rand""net/http""os"&q…

ASP.NET Core 8 在 Windows 上各种部署模型的性能测试

ASP.NET Core 8 在 Windows 上各种部署模型的性能测试 我们知道 Asp.net Core 在 windows 服务器上部署的方案有 4 种之多。这些部署方案对性能的影响一直以来都是靠经验。比如如果是部署在 IIS 下,那么 In Process 会比 Out Process 快;如果是 Self Hos…

Linux 线程池源码剖析

1 了解线程池 1-1线程池的概述 由一个任务队列和一组处理队列的线程组成。一旦工作进程需要处理某个可能“阻塞”的操作,不用自己操作,将其作为一个任务放到线程池的队列,接着会被某个空闲线程提取处理。 1-2线程池的组件 任务 待处理的工作,通常由标识、上下文和处理…

Java_内部类枚举

内部类 内部类: 是类中的五大成分之一(成员变量、方法、构造器、内部类、代码块),如果一个类定义在另一个类的内部,这个类就是内部类。场景:当一个类的内部,包含了一个完整的事物,且这个事物没有必要单独设计时&#x…

年度评选揭晓:Apache SeaTunnel荣获年度优秀开源技术团队殊荣

在OSCHINA平台举办的2023年度开源技术团队评选中,Apache SeaTunnel社区凭借其在开源领域的出色表现,荣获“2023年度优秀开源技术团队”奖项。 这一殊荣不仅是对Apache SeaTunnel社区在过去一年中技术贡献的认可,也是对其在开源社区活动运营方…

聊聊Api接口优化的几个方法!

我负责的系统到2021年初完成了功能上的建设,开始进入到推广阶段。随着推广的逐步深入,收到了很多好评的同时也收到了很多对性能的吐槽。刚刚收到吐槽的时候,我们的心情是这样的: 当越来越多对性能的吐槽反馈到我们这里的时候&…

springboot mybatis手动事务

创建springboot项目 搭建最简单的SpringBoot项目-CSDN博客 引入mybatis和数据库依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><…