C++学习笔记:三种智能指针【Share、Unique、Weak】【Cherno】
老规矩,先问题后文章:
为什么要有智能指针以及它的好处是什么、智能指针是在怎么工作的、智能指针的操作;
1:为什么要有智能指针:
要知道,内存泄漏是非常严重的后果,如果new出来的空间没在合适的时间delete,那么很容易出现bug或者内存泄漏,而合适地用new和delete又是一个特别难的工作,所以C++就推出了智能指针这个概念,其是为了方便程序员管理内存。
大量使用智能指针代替new、delete函数,可以大大地提高程序的稳定性;
2:智能指针是怎么工作的:
个人理解为智能指针是将原始指针封装起来,并结合new、delete、一些必要的函数,因为有delete的参与,所以智能指针可以在适合的时候自动释放;
先介绍智能指针的两个主力:unique、share
unique:
我们先定义一个unique指针:
#include<iostream>
#include<string>
#include<memory>int main() {{std::unique_ptr<int> a = std::make_unique<int>(10);}}
为了某种目的,本菜用一个空作用域将指针围起来;
如果程序出了空作用域,那么系统会自动调用delete函数,将指针和其指向的内容给释放掉;
如果我们将a赋值给其他指向同类型的unique指针:
#include<iostream>
#include<string>
#include<memory>int main() {{std::unique_ptr<int> a = std::make_unique<int>(10);auto b=a;}}
报错:
因为unique的一个特征就是不能有两个指针指向同一个对象,这个特性也导致unique指针不能作为实参传入函数当中;
这种看似无法理解的机制是因为如果多个unique指针指向同一个对象,当其中一个unique指针被释放时,其对象也会被释放,也就是说其他指向这个对象的指针将成为野指针;
下面来看看智能指针自动释放的功能:
#include<iostream>
#include<string>
#include<memory>class temp {
public:temp() {std::cout << "Created" << std::endl;}~temp() {std::cout << "Destroyed" << std::endl;}
};int main() {{std::unique_ptr<temp> a = std::make_unique<temp>();}}
运行结果:
这里我们没有用delete函数,系统就自动释放指针和指向的对象了;
如果我们想要将智能指针传入函数当中,那么我们就需要share指针了:
share指针允许多个share指针指向同一个对象,而且实例化一个share指针时会多出一些内存开销,这些内存会实现一个功能,即引用计数,这个引用计数会记录有多少个share指针指向该对象,当引用计数发现没有指向该对象的指针时,系统就会将该对象释放;
看下面这段代码:
#include<iostream>
#include<string>
#include<memory>class temp {
public:temp() {std::cout << "Created" << std::endl;}~temp() {std::cout << "Destroyed" << std::endl;}
};int main() {std::shared_ptr<temp> a = std::make_shared<temp>();{std::shared_ptr<temp> b = a;}getchar();
}
运行结果【程序停留在getchar()部分】
说明b指针的释放并没有导致b指向的对象被释放,因为还有一个a指针指向该对象,引用计数不为0;
但是如果我们这样写:
#include<iostream>
#include<string>
#include<memory>class temp {
public:temp() {std::cout << "Created" << std::endl;}~temp() {std::cout << "Destroyed" << std::endl;}
};int main() {{std::shared_ptr<temp> a = std::make_shared<temp>();{std::shared_ptr<temp> b = a;}}getchar();
}
运行结果为:
因为到达getchar函数时,两个指针都被释放了,所以对象也跟着被释放了;
然后来谈谈引用计数:
引用计数说白了,就是检测有多少个share指针指向同一个对象,如果为0的话,那么就将调用delete函数将对象清除;
有以下几种情况可以改变引用计数:
(1)当指针方向改变时,引用计数会减小;
(2)当指针被释放时,引用计数会减小;
(2)当指针指向对象时,引用计数会增加;
看以下代码【use_count()函数是share内置的一种函数,功能是返回有多少个share指针指向该对象】
#include<iostream>
#include<string>
#include<memory>class temp {
public:temp() {std::cout << "Created" << std::endl;}~temp() {std::cout << "Destroyed" << std::endl;}
};void get(std::shared_ptr<temp> mid) {std::cout << mid.use_count() << std::endl;}int main() {{std::shared_ptr<temp> a = std::make_shared<temp>();get(a);{std::shared_ptr<temp> b = a;get(b);}get(a);}getchar();
}
运行结果:
这是因为将a传入函数时,函数会生成一个share指针形参,并将a赋值给形参,这个时候就有两个share指针指向同一个对象了,而将a赋值给b时,又多出一个,当b超出作用域时,就少了一个;
当然,有时候我们会希望用一个指向由share指针指向的对象时,不引起share指针引用计数的改变,那么我们就可以用weak指针了,这个指针是为了搭配share指针而产生的。如果我们将上述代码中的形参改为weak指针,那么运行结果为:
好了~这些就是简单的智能指针介绍了,以后本菜还会继续更新;
C++学习笔记:三种智能指针【Share、Unique、Weak】【Cherno】相关推荐
- C++智能指针(二)模拟实现三种智能指针
https://blog.csdn.net/nou_camp/article/details/70186721 在上一篇博客中提到了Auto_ptr(C++智能指针(一)),下面进行模拟实现Auto_ ...
- C++中的三种智能指针分析(RAII思想)
2019独角兽企业重金招聘Python工程师标准>>> 智能指针 首先我们在理解智能指针之前我们先了解一下什么是RAII思想.RAII(Resource Acquisition Is ...
- ssm上传文件进度条_ssm学习笔记-三种文件上传方式
首先需要引入commons-fileupload commons-fileupload commons-fileupload 1.3.3 MultipartFile方式 示例代码: @RequestM ...
- C++ 11 深度学习(六)智能指针综述
以下三种智能指针均为类模板 1.shared_ptr 共享指针 ,多个指针指向同一个对象,最后一个指针被销毁时,这个对象会被释放. 2.week_ptr 是辅助shared_ptr工作的 3.u ...
- C++的4种智能指针剖析使用
1. 智能指针背后的设计思想 我们先来看一个简单的例子: void remodel(std::string & str) {std::string * ps = new std::string ...
- 数组存储与指针学习笔记(三)指针与数组
嵌入式C语言学习进阶系列文章 GUN C编译器拓展语法学习笔记(一)GNU C特殊语法部分详解 GUN C编译器拓展语法学习笔记(二)属性声明 GUN C编译器拓展语法学习笔记(三)内联函数.内建函数 ...
- SurfaceFlinger学习笔记(三)之SurfaceFlinger进程
概述 本系列是基于android Q 即android10 SurfaceFlinger学习笔记(一)应用启动流程 SurfaceFlinger学习笔记(二)之Surface SurfaceFling ...
- 区块链学习笔记21——ETH智能合约
区块链学习笔记21--ETH智能合约 学习视频:北京大学肖臻老师<区块链技术与应用> 笔记参考:北京大学肖臻老师<区块链技术与应用>公开课系列笔记--目录导航页 智能合约简介 ...
- K8S 学习笔记三 核心技术 Helm nfs prometheus grafana 高可用集群部署 容器部署流程
K8S 学习笔记三 核心技术 2.13 Helm 2.13.1 Helm 引入 2.13.2 使用 Helm 可以解决哪些问题 2.13.3 Helm 概述 2.13.4 Helm 的 3 个重要概念 ...
最新文章
- 在Ubuntu 14.04 64bit上使用dig
- 一个很好学习Mysql网站
- 一步步编写操作系统 49 加载内核2
- 2021京东Z世代汽车消费趋势报告:存量与增量的数智化合奏
- android 发送显示广播,如何查看Android系统当前发送了什么广播
- 软件基本功:工作目标经常变化,要及时跟进
- 人工智能AI 生成的艺术:从文本到图像
- Windows10C盘文件简单介绍
- solidworks一份草图多次拉伸与多次凸台
- vue图片裁剪插件:vue-img-cutter
- 瑞利 随机 matlab,matlab产生瑞利分布随机信号
- 【NLP】句法分析一
- GPT磁盘如何正确分区以及UEFI引导怎么修复?
- 【笔记】识别手写数字神经网络
- 深圳市智汇机器人科技有限公司环宇智行
- Android APP如何简单快速实现控制硬件设备并实现APP签名
- 网易校园招聘笔试题目
- c语言程序设计试题汇编第三版勘误,c语言程序设计基础教程----勘误记录.pdf
- ORACLE数据库tnsnames.ora配置文件详细解析
- 罗兰钢琴APP有Android版本吗,罗兰Piano Partner 2安卓版
热门文章
- 程序员的自我进化:学习之道,如何更有效的学习
- js 树形结构数据 已知某一子节点 一次向上获取所有父节点
- lisp 套料_标志排字及过桥的AutoCAD自动化插件设计
- 无法启动此程序因为计算机丢失msvcr110.dll,Win7运行程序提示计算机中丢失msvcr110.dll如何解决...
- Python画玫瑰花
- linux hwclock -r显示的HWC TIME(硬件时钟时间)与timedatectl结果中的RTC TIME(实时时钟时间)有什么区别?BIOS时钟源
- 这个七夕,送你一份程序员教科书级别的告白指南
- 2022版Maven教程 - 第六章 单一架构案例
- PC 音频,视频硬件输出设置
- 分享一些网页设计成品下载