老规矩,先问题后文章:

为什么要有智能指针以及它的好处是什么、智能指针是在怎么工作的、智能指针的操作;

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】相关推荐

  1. C++智能指针(二)模拟实现三种智能指针

    https://blog.csdn.net/nou_camp/article/details/70186721 在上一篇博客中提到了Auto_ptr(C++智能指针(一)),下面进行模拟实现Auto_ ...

  2. C++中的三种智能指针分析(RAII思想)

    2019独角兽企业重金招聘Python工程师标准>>> 智能指针 首先我们在理解智能指针之前我们先了解一下什么是RAII思想.RAII(Resource Acquisition Is ...

  3. ssm上传文件进度条_ssm学习笔记-三种文件上传方式

    首先需要引入commons-fileupload commons-fileupload commons-fileupload 1.3.3 MultipartFile方式 示例代码: @RequestM ...

  4. C++ 11 深度学习(六)智能指针综述

    以下三种智能指针均为类模板 1.shared_ptr  共享指针   ,多个指针指向同一个对象,最后一个指针被销毁时,这个对象会被释放. 2.week_ptr 是辅助shared_ptr工作的 3.u ...

  5. C++的4种智能指针剖析使用

    1. 智能指针背后的设计思想 我们先来看一个简单的例子: void remodel(std::string & str) {std::string * ps = new std::string ...

  6. 数组存储与指针学习笔记(三)指针与数组

    嵌入式C语言学习进阶系列文章 GUN C编译器拓展语法学习笔记(一)GNU C特殊语法部分详解 GUN C编译器拓展语法学习笔记(二)属性声明 GUN C编译器拓展语法学习笔记(三)内联函数.内建函数 ...

  7. SurfaceFlinger学习笔记(三)之SurfaceFlinger进程

    概述 本系列是基于android Q 即android10 SurfaceFlinger学习笔记(一)应用启动流程 SurfaceFlinger学习笔记(二)之Surface SurfaceFling ...

  8. 区块链学习笔记21——ETH智能合约

    区块链学习笔记21--ETH智能合约 学习视频:北京大学肖臻老师<区块链技术与应用> 笔记参考:北京大学肖臻老师<区块链技术与应用>公开课系列笔记--目录导航页 智能合约简介 ...

  9. 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 个重要概念 ...

最新文章

  1. 在Ubuntu 14.04 64bit上使用dig
  2. 一个很好学习Mysql网站
  3. 一步步编写操作系统 49 加载内核2
  4. 2021京东Z世代汽车消费趋势报告:存量与增量的数智化合奏
  5. android 发送显示广播,如何查看Android系统当前发送了什么广播
  6. 软件基本功:工作目标经常变化,要及时跟进
  7. 人工智能AI 生成的艺术:从文本到图像
  8. Windows10C盘文件简单介绍
  9. solidworks一份草图多次拉伸与多次凸台
  10. vue图片裁剪插件:vue-img-cutter
  11. 瑞利 随机 matlab,matlab产生瑞利分布随机信号
  12. 【NLP】句法分析一
  13. GPT磁盘如何正确分区以及UEFI引导怎么修复?
  14. 【笔记】识别手写数字神经网络
  15. 深圳市智汇机器人科技有限公司环宇智行
  16. Android APP如何简单快速实现控制硬件设备并实现APP签名
  17. 网易校园招聘笔试题目
  18. c语言程序设计试题汇编第三版勘误,c语言程序设计基础教程----勘误记录.pdf
  19. ORACLE数据库tnsnames.ora配置文件详细解析
  20. 罗兰钢琴APP有Android版本吗,罗兰Piano Partner 2安卓版

热门文章

  1. 程序员的自我进化:学习之道,如何更有效的学习
  2. js 树形结构数据 已知某一子节点 一次向上获取所有父节点
  3. lisp 套料_标志排字及过桥的AutoCAD自动化插件设计
  4. 无法启动此程序因为计算机丢失msvcr110.dll,Win7运行程序提示计算机中丢失msvcr110.dll如何解决...
  5. Python画玫瑰花
  6. linux hwclock -r显示的HWC TIME(硬件时钟时间)与timedatectl结果中的RTC TIME(实时时钟时间)有什么区别?BIOS时钟源
  7. 这个七夕,送你一份程序员教科书级别的告白指南
  8. 2022版Maven教程 - 第六章 单一架构案例
  9. PC 音频,视频硬件输出设置
  10. 分享一些网页设计成品下载