来自公众号:编程技术宇宙

1

栈里的对象

"构造完毕,请睁开眼吧!",迷迷糊糊中,听着这个声音,我睁开了眼睛,一位小哥映入眼帘。“你是谁?我是谁?这又是什么地方?”,我的大脑一片空白。“你是一个C++对象,这里是栈空间。我是创建你的线程,你先待着,一会儿会用到你,拜~”“唉,等一下...”,还没等我回过神,小哥已经走远。

环顾四周,这个叫栈的地方,有好多好多的对象,大小不一,不远处还有一个巨无霸对象足足有好几千字节。“哇!好大一个对象!”,我不禁发出了惊叹。“一看就是没见过世面的,这才多小的个头,就在那大呼小叫的”,突然传来一个声音。“谁在说话?”,我四处望去,却没发现动静。“往哪看呢,没那么远,就在你旁边”,我这才注意到眼皮底下有个小个子在说话。“你才8个字节的对象,好大的口气!”“唉,纠正一下,我可不是对象哦,我只是一个指针,我指向的对象那才叫大呢!”原来这小个子是个指针,顺着他指向的地址望去,果然有一庞然大物,虽不见其全身,估摸着至少也有几MB的大小。“唉,你指向的对象为何不和我们在一块儿,我看那地方好像不属于栈的地界儿了”。“说你没见过世面,你还不承认。咱们这栈空间有限,哪里装得下那么多大对象,他们那里叫堆区,一般有身份的对象都放在那边的。那里的对象都是通过new关键字生成的,你们可没这待遇哦,还有...““嘘!先别说话,你看线程小哥在干嘛?”,看到之前的小哥去了堆区,我打断了指针小个子的说话。

2

堆里的对象

只见小哥执行malloc函数在堆区划了一片空间,接着调用构造函数在那片空间上创建了一个对象。“你刚才不是说那里的对象是new出来的吗,骗人!”“这你都不知道,这个new = 内存分配 + 构造函数,而内存分配一般默认就是malloc,不懂还一惊一乍的,切~”,被指针小个子怼了回来,我真想找个缝躲起来。正在我难为情的时候,线程小哥又来到了栈区,在我的头上不远处又创建了一个对象。

“你们好,我是新来的,请多指教!”

“欢迎欢迎,你好,请问你是?”,我第一个上前打招呼。

“咦,你手里怎么握着刚刚那个新对象的地址呢?你也是个指针吗,怎么跟我长得不一样”,小个子指针也凑了上来。

“这位老弟果然好眼力,我也确实是个指针,不过啊,你只是个裸指针,而我是个智能指针!”,新来这小子言语间透露着一股傲娇的味道。“智能指针?这是个啥?”,小个子指针继续追问。“哎哟,没想到见多识广的你也有不知道的事嘛!哈哈”,我趁此机会嘲笑了一把小个子。

3

智能指针

“好吧,那我就自我介绍下,我是一个shared_ptr,人类将我叫做智能指针,我手里握着一个裸指针,弥补了直接使用裸指针带来的烦恼!现在人类可喜欢用我们了。”“烦恼?什么烦恼?”,小个子指针有点不太服气。“当然是内存泄漏啦!像你们直接使用new创建出来的对象,程序员们要是忘记写delete释放,那这对象就成为被抛弃的孤儿,就会白白占用堆空间。一个两个还好,要是是在一个频繁执行的函数中发生这种事情,那堆空间就被这些抛弃的对象占满,那后果不堪设想!”,说完,智能指针的嘴角扬起了微笑。“哦,还没完呢,裸指针还有个毛病就是谁来释放的问题,因为你们裸指针就是一个地址,可以在函数之间四处传递,最后传来传去,到底谁来释放,是不是还有别的函数和线程在使用都搞不清楚了,要是不释放呢,就内存泄漏了,要是别人还在用呢,释放了又会出问题,所以怎么着都很恼火”,说完,智能指针嘴角又上扬了许多。小个子指针听完有些气馁,停顿一会之后再一次发出了疑问:“那你们是如何解决这个问题的呢?”“我的内部有一个计数器,初始创建完对象后,把地址告诉了我,计数器值是1,以后每次把我赋值给别的智能指针,或者是函数传参拷贝到另一个shared_ptr,我的计数器值都会+1,表示又多了一个shared_ptr在使用它,相反的如果有一个shared_ptr对象析构了,那计数器值就-1。直到最后谁发现了这个计数器变为0,说明没人在用这个对象了,那就执行delete把它释放掉。看,是不是很聪明呐!”“唉,我听明白了,原来你shared_ptr自己也是一个对象,利用自己的构造函数和析构函数来对一个计数器进行增加和减少操作来实现对裸指针指向对象的管理,是这样吧?”,我接上了这小子的话茬。“对,没错,这个叫引用计数!我本身和你一样,也是一个对象哦,咱们这些在栈里的对象,有一个特别大的好处就是不用担心会内存泄漏,也不用担心析构函数不会被调用,编译器在生成指令的时候都已经自动做好了。”

4

智能指针的帮手

看着我俩打得火热,小个子指针不开心了,“有什么了不起,我能说出一种情况,就让你当场下不来台,哼!”“哦,你倒是说说看?”“如果两个对象A和B,A里面有个shared_ptr指向B,B里面有个shared_ptr指向A,也就是互相引用了,这样子,你们两个shared_ptr计数器永远是1,谁也释放不了,怎么样,没辙了吧!哈哈”,小个子一边说一边拍自己大腿,乐得不行。

我还在脑子里冥想这到底是个什么场景,智能指针开始回怼了:“你说的这种情况一早就想到了,在遇到互相引用的时候,我就要请出我的助手weaked_ptr了,它和我功能类似,最大的区别就是它不增加引用计数,只要A和B其中一方把shared_ptr换成weaked_ptr,就能打破你说的循环!”

小个子没料到这智能指针居然还有帮手,一下子语塞,最后实在没办法,憋出了一句:“你是厉害,可是很多现成的模块接口都是裸指针作为参数,要是用你肯定好多不兼容,还得我们裸指针上。”“唉,此言差矣,既然是智能指针,这点困难都解决不了,哪有脸敢称智能两字?我们重载了->运算符和*运算符,让人类用起我们来和普通指针一样的体验。还提供了get()方法提供原始指针,在遇到你说的情况下也能用得上。怎么样,这下服了吧?唉,你别走啊,真小气~”原来没等他说完,小个子指针已经灰溜溜的躲开了。未完待续·······


●编号706,输入编号直达本文

●输入m获取文章目录

C语言与C++编程

分享C/C++技术文章

智能指针的释放_堆栈里的悄悄话——智能指针相关推荐

  1. 智能指针的释放_手把手教你实现智能指针

    一. 为什么使用智能指针 C++的内存管理是让很多人头疼的事,因为C++语言中没有垃圾回收机制,当我们通过new语句动态申请堆空间时,用完这个堆空间时就得用delete语句释放申请的堆空间,不然就会导 ...

  2. 智能指针的释放_看完这篇,别再说不会智能指针了

    C++智能指针 一.智能指针的作用 上一篇介绍了内存池的原理和实现,详情请见内存池设计与实现: 内存池可以帮助我们有效的对内存进行管理,智能指针可以很方便的管理指针,避免出现内存泄漏: 智能指针的作用 ...

  3. arduino智能浇花系统_创新成果 | 养花神器——智能浇花机

    养花的人应该多少都会遇到这样的问题:需要根据花的习性定时浇水,但给花浇水是个「技术活」,不记得浇水或水浇多了,都会影响花的生长. 针对这个问题,可以研究制作一个简单.实用的自动浇花机.根据检测土壤的湿 ...

  4. 什么是智能合约 区块链_什么是区块链智能合约?

    什么是智能合约 区块链 关于区块链智能合约的第一件事是它们不是智能合约,或者不是区块链上的合约. 实际上,它们的名字是奇异的. 1 ,让我们将按照相反的顺序这些问题,我们应该搞清楚一个聪明的合同实际上 ...

  5. 指针数组 c ++_了解C ++中的数组指针

    指针数组 c ++ 介绍 (Introduction) Today in this tutorial, we are going to understand the concept of the Po ...

  6. c++ 对象起始地址 指针靠齐_你需要知道的各种指针运算

    数组的某个成员可以用数组的基地址加上一个偏移量来表示.我们可以声明一个指针double *p;,把它作为基地址,然后就可以像数组一样在这个基地址上使用偏移量.在基地址上,我们可以找到第1个成员p[0] ...

  7. a113 智能音箱芯片方案_高通入局智能音箱,首款四核单芯片方案曝光

    不得不说,智能音箱已经成为目前重要的科技品类之一,许多公司包括亚马逊.谷歌.苹果.阿里巴巴.小米等等,都在大举进军智能音箱市场. 为了尽可能为更多产品提供核心原件,近日,高通公司推出了一款全新的SOC ...

  8. 基于python的智能安防系统_基于Python语言的智能家居系统研究

    龙源期刊网 http://www.qikan.com.cn 基于 Python 语言的智能家居系统研究 作者:张微微

  9. arduino智能浇花系统_基于Arduino单片机的智能浇花器

    Internal Combustion Engine & Parts • 119 • 基于Arduino单片机的智能淺花器 卞 云 松 ;张 国 祥 ;任 佳 豪 :陆晨雨 (江海职业技术学院 ...

最新文章

  1. 深入浅出LSTM神经网络
  2. 14.4 线程通讯-生产者与消费者
  3. Fiddler本机调试的方法
  4. java snychronized_Java synchronized同步线程机制(三) | 学步园
  5. 可用于 线性判别、聚类分析 的R语言函数总结
  6. 合泰单片机市场占有率_holtek单片机图文全面详解
  7. 关于获取多个屏幕分辨率以及进行一些设置
  8. CImageList-CBitmap-Usage
  9. 大话Seq2Seq模型
  10. wpa_supplicant交叉编译
  11. 如何在Mozilla Firefox中启用(或禁用)Cookie
  12. 关于泛型中包含级联的List转化为json数据的处理
  13. Spring Framework框架起步,小白都看得懂(官翻版)!
  14. Minimal Area
  15. TypeError错误解决方案
  16. XDOJ 378 正整数的最优分解
  17. 经济研究之关于ROE指标//2021-2-3
  18. 什么是Linux,它能干嘛?
  19. 微软CRM与知客CRM简介及互补营销
  20. (30)Verilog实现倍频【方法一】

热门文章

  1. mysql 设置一个字段为null_MySQL中,为什么要设置NOT NULL?
  2. C++之指针探究(十四):回调函数
  3. C++之关于虚函数和多态的分析和补充
  4. linux网卡握手速率模式,一种基于Linux平台下的网卡速率和双工模式测试的方法与流程...
  5. java 反射 proper_JAVA提高四:反射基本应用
  6. vs2015项目导出为Qt项目
  7. mips linux gcc mingw,gcc
  8. cocos 时间函数需要什么引用_与时间赛跑:微盟的数据恢复为什么需要这么长时间...
  9. Spring mvc 中文乱码
  10. javascript 对象属性