C++学习笔记-C++11中的智能指针

1.智能指针介绍

智能指针是C++的特性用法,是一个类似指针功能的类对象,其目的是为了更好的管理动态分配的内存,避免出现内存泄漏、悬空指针等问题。C++11的标准库里提供了三种智能指针模板类,分别是std::unique_ptr、std::shared_ptr 和 std::weak_ptr(C++11摒弃了auto_ptr)。

2.为什么需要智能指针

首先来看一段代码

void test(std::string& str)
{std::string* ps = new std::string("nihao!\n");str = *ps;//delete ps;return;
}

不难发现代码的隐患问题,每次函数被调用时,ps指针指向的内存空间都分配在堆上,但是在没有delete ps语句的情况下,无论是函数结束还是异常退出,都无法释放内存。然后我们在面对复杂逻辑的编程时,常常会忘记使用delete,这就会导致内存泄漏。
于是我们就会想,如果在函数终止时(不管是正常终止还是异常终止),new出来的内存都像函数内部的局部变量从栈内存上释放那样,从堆上释放,那就很巴适。智能指针的设计就是解决这样的问题。
来看下面这段代码:

void test_auto(std::string& str)
{std::unique_ptr<std::string> ps(new std::string("nihaoya!\n"));str = *ps;return;
}

使用了智能指针模版类后,因为是通过类来管理我们申请的资源,类的析构函数在类对象出作用域的时候会自动被调用,会自动的清理申请的资源。即使没有delete语句,在函数终止时,指针占据的内存空间和指针指向的内存空间都将被释放。

3. 智能指针用法示例

3.1 独占性智能指针std::unique_ptr

所谓的独占型,即两个unique_ptr不能指向同一个对象,指针直接不能复制,只能将所有权通过move接口转移。
看如下一段代码:

std::unique_ptr<std::string>p1(new std::string("hai\n"));	// 1
std::unique_ptr<std::string>p2;								// 2
p2 = p1;													// 3
p2 = move(p1);												// 4
std::cout << *p1 << std::endl;								// 5
std::cout << *p2 << std::endl;								// 6

其中,第三条p2 = p1;是不被允许的,编译系统提示如下。

第5条std::cout << *p1 << std::endl;由于是经过move后,p1指针的内容为空,运行将产生如下报错。
在这里插入图片描述

屏蔽掉报错内容后,系统运行结果如下,将p1指针转移到p2指针,并销毁p1指针内容。
在这里插入图片描述

3.2 共享型智能指针std:: shared_ptr

共享指针shared_ptr是只具有共享所有权语义的智能指针。 每当共享指针shared_ptr的最后一个所有者被销毁时,关联对象都将被删除(或关联资源被清除),允许多个指针指向同一个变量。

3.3 弱引用智能指针std:: weak_ptr

weak_ptr专门为了解决std:: shared_ptr循环引用问题而引入的指针类型,通过shared_ptr构造,配合shared_ptr才能使用,它指向一个由shared_ptr管理的对象而不影响所指对象的生命周期,也就是,将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。不论是否有weak_ptr指向,一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放。从这个角度看,weak_ptr更像是shared_ptr的一个助手而不是智能指针。
那么,什么是循环引用的问题呢?在shared_ptr的使用过程中,当强引用计数为0是,就会释放所指向的堆内存。那么问题来了,如果和死锁一样,当两个shared_ptr互相引用,那么它们就永远无法被释放了。

3.4 选择智能指针

如果程序需要使用多个指向同一对象的指针,应选择share_ptr,当程序中存在循环调用的逻辑时,选择weak_ptr指针来辅助,反之若不需要多个指针指向同一个对象,则选择unique_ptr。

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

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

相关文章

苹果笔记本电脑如何优化系统 苹果电脑系统优化软件哪个好 cleanmymac x怎么用

随着时间的推移&#xff0c;你可能会发现你的MacBook运行速度变慢&#xff0c;甚至在执行一些基本任务时也会感觉到卡顿。这不仅影响了工作效率&#xff0c;也大大降低了使用体验。但别担心&#xff0c;优化你的Mac系统比做早餐还简单。本文将用一种轻松的风格向你介绍7种简单易…

函数的介绍

目录 一、函数介绍 1、函数的介绍 2、自定义函数 3、函数的好处 二、函数的定义 1、函数的定义 2、函数的调用 3、快速入门案例 三、函数-调用机制 1、函数-调用过程 2、return语句 一、函数介绍 1、函数的介绍 1&#xff09;为了完成某一功能的程序指令(语句)的集…

【Postgres实战】Postgres的角色权限本地/在线不一致?

背景 Gin-Vue-Admin是开源的全栈开发平台&#xff0c;可以担任企业内部后台管理的职责。官网地址是&#xff1a;gin-vue-admin | GVA 文档站。上图为在线demo展示页面。 它的后台使用Golang&#xff08;The Go Programming Language (google.cn)&#xff09;&#xff0c;基于…

JSON 文件第一段飘红

问题 原因 这个问题通常发生在尝试用 ESLint 去解析 JSON 文件时。ESLint 主要设计用于检查 JavaScript 代码的语法和风格&#xff0c;而JSON是一种数据交换格式&#xff0c;不包含 JavaScript 的逻辑结构&#xff0c;如函数、变量声明等。 解释报错原因 当ESLint遇到它不能识…

让 AI 开发更高效、低成本,DigitalOcean 公布 GPU Droplet 云主机产品

全球知名云服务供应商 DigitalOcean 在近期举行的 Deploy 大会上公布了全新的 GPU Droplet 云主机服务&#xff0c;这标志着DigitalOcean 在支持AI和机器学习工作负载方面迈出了重要一步。 DigitalOcean 的 GPU Droplet&#xff08;云主机&#xff09; DigitalOcean 自 2023 …

【STM32嵌入式系统设计与开发拓展】——12_Timer(定时器中断实验)

目录 1、什么是定时器&#xff1f;定时器用于测量时间间隔&#xff0c;而计数器用于计数外部事件的次数 2、定时器的主要功能和用途&#xff1f;3、定时器类型&#xff1f;4、定时器的编写过程5、代码分析定时器计算&#xff1f; 1、什么是定时器&#xff1f; 定时器就是计数器…

正点原子STM32(基于HAL库)6

目录 TFTLCD&#xff08;MCU 屏&#xff09;实验TFTLCD 简介TFTLCD 简介液晶显示控制器FSMC 简介FSMC 关联寄存器简介 硬件设计程序设计FSMC 和SRAM 的HAL 库驱动程序流程图程序解析 下载验证 LTDC LCD&#xff08;RGB 屏&#xff09;实验RGBLCD<DC 简介RGBLCD 简介LTDC 简介…

力扣高频SQL 50题(基础版)第九题

文章目录 力扣高频SQL 50题&#xff08;基础版&#xff09;第九题197. 上升的温度题目说明思路分析实现过程准备数据实现方式结果截图总结 力扣高频SQL 50题&#xff08;基础版&#xff09;第九题 197. 上升的温度 题目说明 Weather ---------------------- | Column Name…

深度学习实战笔记2实战Kaggle比赛:预测房价

此数据集由Bart de Cock于2011年收集 :cite:De-Cock.2011&#xff0c; 涵盖了2006-2010年期间亚利桑那州埃姆斯市的房价。 这个数据集是相当通用的&#xff0c;不会需要使用复杂模型架构。 它比哈里森和鲁宾菲尔德的波士顿房价 数据集要大得多&#xff0c;也有更多的特征。 1下…

数据结构之深入理解简单选择排序:原理、实现与示例(C,C++)

文章目录 一、简单选择排序原理二、C/C代码实现总结&#xff1a; 在计算机科学中&#xff0c;排序算法是一种非常基础且重要的算法。简单选择排序&#xff08;Selection Sort&#xff09;作为其中的一种&#xff0c;因其实现简单、易于理解而受到许多初学者的喜爱。本文将详细介…

El-Table 表格的表头字段切换

最近写了一个小功能&#xff0c;比较有意思&#xff0c;特此博客记录。 提出需求&#xff1a;需要表头字段变化&#xff0c;但是我在官网上的表格相关上查找&#xff0c;没有发现便捷方法。 于是我有两个想法&#xff1a;1.做三个不同的表格。2.做一个表格使用不同的表头字段。…

python如何调用matlab python package库matlab转python安装包调用使用简单示例

说明(废话) 之前没有进行python调用过matlab&#xff0c;前面用matlab engine for python可以通过调用matlab的源码文件的形式可以调用工程&#xff0c;但是这又有一个问题&#xff0c;就是在运行的时候必须提供python和matlab的全部源码 该文章是通过matlab源码转python pack…

cdp碳信息披露

在全球化日益加深的今天&#xff0c;环境保护和可持续发展已成为全球共识。企业作为经济社会的主体&#xff0c;其在环保领域的行动和决策不仅影响着自身的发展&#xff0c;更对整个社会乃至全球的生态环境产生深远影响。CDP&#xff08;Carbon Disclosure Project&#xff0c;…

很酷的仿真翻页书HTML源码,书本页面是加载的图片,基于JQuery实现的翻页特效,结合一些js插件,看起来很酷,在实现在线翻书项目。

仿真翻页书HTML源码https://www.bootstrapmb.com/item/14742 创建一个仿真的翻页书效果在HTML和CSS中可以通过多种方式实现&#xff0c;但通常这也会涉及到JavaScript&#xff08;或jQuery&#xff09;来处理交互和动画。以下是一个简单的示例&#xff0c;展示如何使用HTML、…

【Leetcode】十八、动态规划:不同路径 + 全1的最大正方形

文章目录 1、动态规划2、leetcode509&#xff1a;斐波那契数列3、leetcode62&#xff1a;不同路径4、leetcode121&#xff1a;买卖股票的最佳时机5、leetcode70&#xff1a;爬楼梯6、leetcode279&#xff1a;完全平方数7、leetcode221&#xff1a;最大正方形 1、动态规划 只能…

10KW级电机电流特性曲线推导及校验

1.首先进行数据拟合 2.拟合曲线依照电机参数标准化 30A处转差率应为6.6%。 3.全域电流对照表&#xff1a; 4.实际的电流年变化曲线&#xff08;因为电压不稳定&#xff09; 4.1 以日为单位的电流起伏 蓝色的部分标出了工作日的切换。 4.2 某个月的电流趋势图&#xff1a;

argon主题调整日记

前言 argon主题是一款由solstice23开发的一款简洁美观的WordPress主题&#xff0c;在使用过程中也发现了几个可以优化的点&#xff0c;在查阅主题文档无果后对其进行以下几点修改。 1、使用子主题 为了避免修改源文件而引起主题更新后修改丢失的问题&#xff0c;还是尽量使用子…

C# yaml 配置文件的用法(一)

目录 一、简介 二、yaml 的符号 1.冒号 2.短横杆 3.文档分隔符 4.保留换行符 5.注释 6.锚点 7.NULL值 8.合并 一、简介 YAML&#xff08;YAML Aint Markup Language&#xff09;是一种数据序列化标准&#xff0c;广泛用于配置文件、数据交换和存储。YAML的设计目标是…

【Java 数据结构】ArrayList类介绍

ArrayList类介绍 初识List接口ArrayList类ArrayList类是什么顺序表的模拟实现初始化增加元素删除元素查找元素修改元素 ArrayList类使用构造方法ArrayList源码阅读常用方法及其注意事项 初识List接口 List 是集合框架中的一个接口, 它的里面包含了一些方法, 例如add(), remove…

记录下 java.lang.UnsatisfiedLinkError 错误

java.lang.UnsatisfiedLinkError 错误 java.lang.UnsatisfiedLinkError 错误解决方式一解决方式二 前因&#xff1a;在我的项目中调用到设备&#xff0c;使用厂家提供的sdk中有dll文件调用&#xff0c;在项目中引用dll文件提示了异常&#xff0c;奇怪的是如果把dll直接copy放在…