文库网
ImageVerifierCode 换一换
首页 文库网 > 资源分类 > PPT文档下载
分享到微信 分享到微博 分享到QQ空间

《面向对象程序设计C++》课件1第3章 类和对象-动态内存与智能指针.ppt

  • 资源ID:20014291       资源大小:1.20MB        全文页数:29页
  • 资源格式: PPT        下载积分:10文币
微信登录下载
快捷下载 游客一键下载
账号登录下载
三方登录下载: QQ登录 微博登录
二维码
扫码关注公众号登录
下载资源需要10文币
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
如填写123,账号就是123,密码也是123。
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 
账号:
密码:
验证码:   换一换
  忘记密码?
    
友情提示
2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

《面向对象程序设计C++》课件1第3章 类和对象-动态内存与智能指针.ppt

1、2023/12/21 学习要点学习要点shared_ptrunique_ptrweak_ptr第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针2023/12/22 学习目标学习目标第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针了解三种智能指针shared_ptr、unique_ptr和weak_ptr2023/12/23shared_ptr:是一个模板类,定义在是一个模板类,定义在头文件里。头文件里。shared_ptr对象会在其作用域结束时,自动销毁,对象会在其作用域结束时,自动销毁,如果该如果该shared_ptr是指向某动态对象是指向某动态对象a的最

2、后一个的最后一个shared_ptr,那么,那么a所在的内存会被释放。所在的内存会被释放。第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针2023/12/24unique_ptr:也是一个模板类,同样定义在也是一个模板类,同样定义在头文件头文件里。与里。与shared_ptr不同的是,不同的是,unique_ptr是自己是自己“拥有拥有”一个指向的对象,也就是说不允许有两个或一个指向的对象,也就是说不允许有两个或者以上的者以上的unique_ptr指向同一个对象。在一个指向同一个对象。在一个unique_ptr对象的作用域结束时,对象的作用域结束时,unique_ptr指向指

3、向的对象的内存被释放。为了保证的对象的内存被释放。为了保证unique_ptr对对象对对象的独有性,赋值、复制操作是不允许的。但有一个的独有性,赋值、复制操作是不允许的。但有一个例外,可以在函数中例外,可以在函数中return一个一个unique_ptr。第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针2023/12/25weak_ptr:同样也是一个模板类,定义在同样也是一个模板类,定义在 头文件头文件中。它是为了辅助中。它是为了辅助shared_ptr而引入的一种智能指而引入的一种智能指针,它是一种弱引用,指向针,它是一种弱引用,指向shared_ptr所管理的对所管理的

4、对象,但不增加象,但不增加shared_ptr的引用计数。它存在的意的引用计数。它存在的意义就是协助义就是协助shared_ptr更好的完成工作,可以把它更好的完成工作,可以把它比做成一个秘书或助理。比做成一个秘书或助理。第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针2023/12/26第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针shared_ptr sp空智能指针,可以指向类型为空智能指针,可以指向类型为T的对象的对象unique_ptr upp将将p作为一个判断条件,若作为一个判断条件,若p指向一个指向一个对象,则为对象,则为true*p解引用解引

5、用p,获得它指向的对象,获得它指向的对象p-mem等价于等价于(*p).memp.get()返回返回p中保存的指针中保存的指针swap(p,q)交换交换p和和q中的指针中的指针p.swap(q)表表3-2 shared_ptr3-2 shared_ptr和和unique_ptrunique_ptr都支持的操作都支持的操作2023/12/27第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针make_shared(args)返回一个返回一个shared_ptr,指向一个动态分配,指向一个动态分配的类型为的类型为T的对象。使用的对象。使用args初始化此对初始化此对象象shared

6、_ptrp(q)p是是shared_ptr q的拷贝,此操作会递增的拷贝,此操作会递增q中的计数器,中的计数器,q中的指针必须能转换为中的指针必须能转换为T*p=qp和和q都是都是shared_ptr,所保存的指针必须,所保存的指针必须能相互转换,此操作会递减能相互转换,此操作会递减p的引用计数,的引用计数,递增递增q的引用计数,若的引用计数,若p的引用计数变为的引用计数变为0,则将其管理的原内存释放。,则将其管理的原内存释放。p.unique()若若p.use_count()为为1,返回,返回true,否则返,否则返回回falsep.use_count()返回与返回与p共享对象的智能指针数量

7、,可能共享对象的智能指针数量,可能很慢,主要用于调试很慢,主要用于调试表表3-3 shared_ptr3-3 shared_ptr独有的操作独有的操作2023/12/281、shared_ptr:/指向指向string类型的空指针,默认初始化的智能指针是一个空类型的空指针,默认初始化的智能指针是一个空指针指针shared_ptr p1;shared_ptr p2;/指向指向int类型的空指针类型的空指针/指向一个值为指向一个值为10的的int类型的指针类型的指针shared_ptr p3(new int(10);第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针2023/12/

8、291、shared_ptr:/错误:不能将一个内置指针直接赋值给一个智能指针错误:不能将一个内置指针直接赋值给一个智能指针shared_ptr p4=new int(1);/p5为指向一个值为为指向一个值为1的的int类型的类型的shared_ptrshared_ptr p5=make_shared(1);第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针2023/12/2101、shared_ptr:/p6为指向一个值为为指向一个值为9999999999的的string类型的类型的shared_ptrshared_ptr p6=make_shared(10,9);/p7指向

9、一个值初始化的指向一个值初始化的int,即,值为,即,值为0shared_ptr p7=make_shared();第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针2023/12/2111、shared_ptr:shared_ptr的复制和赋值:当进行复制或赋值操作的复制和赋值:当进行复制或赋值操作时,时,每个每个shared_ptr都会记录有多少个其他都会记录有多少个其他shared_ptr指向相同的对象。指向相同的对象。/p指向的对象只有指向的对象只有p一个引用者一个引用者auto p=make_shared(1);/p和和q指向相同对象,此对象有两个引用者指向相同对象,

10、此对象有两个引用者auto q(p);第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针2023/12/212第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针1、shared_ptrv每个每个shared_ptr都有一个关联的计数器,通常称其都有一个关联的计数器,通常称其为引用计数为引用计数。v无论何时无论何时复制复制一个一个shared_ptr,计数器都会递增。,计数器都会递增。v当给当给shared_ptr赋予一个新值,或者是赋予一个新值,或者是shared_ptr被销毁(比如一个被销毁(比如一个shared_ptr离开其作用域)时,计离开其作用域)时,计

11、数器就会递减。数器就会递减。v一旦一个一旦一个shared_ptr的计数器变为的计数器变为0,它就会自动释,它就会自动释放所管理的对象放所管理的对象:2023/12/213第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针使用使用shared_ptr注意事项:注意事项:(1)不要混合使用普通指针和)不要混合使用普通指针和shared_ptr指针指针(2)不要使用)不要使用get初始化另一个初始化另一个shared_ptr指针或为指针或为shared_ptr指针赋值指针赋值:2023/12/214第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针表表3-4 3-4

12、 定义和改变定义和改变shared_ptrshared_ptr的其他方法的其他方法shared_ptrp(q)p管理内置指针q所指向的对象,q必须指向new分配的内存,且能转换为T*类型shared_ptrp(u)p从unique_ptru那里接管了对象的所有权,将u置为空shared_ptrp(q,d)p接管了内置指针q所指向的对象的所有权,q必须能转换为T*类型,p将使用可调用对象d来代替deleteshared_ptrp(p2,d)p是shared_ptrp2的拷贝,唯一的区别是p将用可调用对象d来代替deletep.reset()当智能指针中有值的时候,调用reset()会使引用计数减

13、1。如果发现此时p的引用计数为0时,则reset会释放p对象。p.reset(q)p.reset(q,d)若传递了可选参数内置指针q,会将p的引用计数减1(当然,如果发现引用计数为0时,则自动释放p所管理的对象),然后令p指向q。若还传递了参数d,将会调用d而不是delete来释放q。2023/12/215第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针为了正确使用智能指针,必须坚持以下基本规范:为了正确使用智能指针,必须坚持以下基本规范:(1)不使用相同的内置指针值初始化(或)不使用相同的内置指针值初始化(或reset)多)多个个shared_ptr,原因在于,会造成二次销

14、毁。,原因在于,会造成二次销毁。int*p8=new int;shared_ptr p9(p8);shared_ptr p10(p8);/逻辑错误逻辑错误(2)不)不delete get()返回的指针。返回的指针。(3)如果使用)如果使用get()返回的指针,记住当最后一个对返回的指针,记住当最后一个对应的智能指针销毁后,该指针就变为无效了。应的智能指针销毁后,该指针就变为无效了。:2023/12/216第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针为了正确使用智能指针,必须坚持以下基本规范:为了正确使用智能指针,必须坚持以下基本规范:(4)默认情况下,一个用来初始化智能指

15、针的普通指)默认情况下,一个用来初始化智能指针的普通指针必须指向动态内存,因为智能指针默认使用针必须指向动态内存,因为智能指针默认使用delete来释放它所关联的对象。也可以把智能指针绑定到其来释放它所关联的对象。也可以把智能指针绑定到其他类型的指针上,但是我们必须提供自己的删除操作他类型的指针上,但是我们必须提供自己的删除操作来替代来替代delete。(5)避免循环引用。智能指针最大的一个陷阱是循环)避免循环引用。智能指针最大的一个陷阱是循环引用,循环引用会导致内存泄漏。解决方法是改用引用,循环引用会导致内存泄漏。解决方法是改用weak_ptr。见下面的例。见下面的例3-16。:2023/1

16、2/2172、unique_ptrv一个一个unique_ptr“拥有拥有”它所指向的对象,与它所指向的对象,与shared_ptr不同,某个时刻只能有一个不同,某个时刻只能有一个unique_ptr指向指向一个给定的对象,一个给定的对象,unique_ptr被销毁时,其所指向的对被销毁时,其所指向的对象也被销毁了。象也被销毁了。v定义一个定义一个unique_ptr指针时,必须将其绑定到一个指针时,必须将其绑定到一个new返回的指针上。类似返回的指针上。类似shared_ptr,初始化,初始化unique_ptr必须采用直接初始化形式。必须采用直接初始化形式。/p1为指向一个为指向一个dou

17、ble类型的类型的unique_ptr unique_ptr p1;/p2为指向一个值为为指向一个值为10的的int类型的类型的unique_ptr unique_ptr p2(new int(10);第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针2023/12/2182、unique_ptrv由于一个由于一个unique_ptr拥有它指向的对象,因此拥有它指向的对象,因此unique_ptr不支持普通的不支持普通的复制复制或赋值操作或赋值操作unique_ptr p1(new string(good);unique_ptr p2(p1);/错误,不支持错误,不支持复制复制

18、操作操作unique_ptr p3;p3=p2;/错误,不支持赋值操作错误,不支持赋值操作第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针2023/12/2192、unique_ptrv但可以通过但可以通过release和和reset方法将指针的所有权从一方法将指针的所有权从一个个(非非const)unique_ptr转移给另一个转移给另一个unique_ptr。/p1放弃所有权,转交给放弃所有权,转交给p2,release将将p1置空置空unique_ptr p2(p1.release();unique_ptr p3(new string(better);/p3放弃所有权,

19、转交给放弃所有权,转交给p2p2.reset(p3.release();/reset释放了释放了p3原来指向的内原来指向的内存存注意:注意:release()并不会释放内存只会转交拥有权,并不会释放内存只会转交拥有权,reset()可以释放内存。可以释放内存。第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针2023/12/2202、unique_ptrv不能不能复制复制unique_ptr的规则有一个例外:可以的规则有一个例外:可以复制复制或或赋值一个将要被销毁的赋值一个将要被销毁的unique_ptr。v从函数返回一个从函数返回一个unique_ptr:unique_ptr

20、 clone(int p)/正确:从正确:从int*创建一个创建一个unique_ptr return unique_ptr(new int(p);第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针2023/12/2212、unique_ptrv不能不能复制复制unique_ptr的规则有一个例外:可以的规则有一个例外:可以复制复制或或赋值一个将要被销毁的赋值一个将要被销毁的unique_ptr。v还可以返回一个局部对象的还可以返回一个局部对象的复制复制:unique_ptr clone(int p)unique_ptr ret(new int(p);/正确正确 return

21、ret;第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针2023/12/2222、unique_ptrvunique_ptr中的删除器:类似中的删除器:类似shared_ptr,unique_ptr默认情况下用默认情况下用delete释放它指向的对象。与释放它指向的对象。与shared_ptr一样,可以重载一个一样,可以重载一个unique_ptr中默认的删中默认的删除器。但是,除器。但是,unique_ptr管理删除器的方式与管理删除器的方式与shared_ptr不同,在构建时必须提供删除器的类型。不同,在构建时必须提供删除器的类型。第第3章章 类和对象类和对象-动态内存与

22、智能指针动态内存与智能指针2023/12/2233、weak_ptrvweak_ptr是一种不控制所指向对象生存期的智能指针,是一种不控制所指向对象生存期的智能指针,它指向一个它指向一个shared_ptr管理的对象。将一个管理的对象。将一个weak_ptr绑定到绑定到shared_ptr不会改变不会改变shared_ptr的引用计数。一的引用计数。一旦最后一个指向对象的旦最后一个指向对象的shared_ptr被销毁,对象就会被被销毁,对象就会被释放,即使有释放,即使有weak_ptr指向对象,对象还是会被释放。指向对象,对象还是会被释放。v当我们创建一个当我们创建一个weak_ptr时,要用

23、一个时,要用一个shared_ptr来来初始化它:初始化它:auto p=make_shared_ptr(10);/wp弱共享弱共享p,p的引用计数未改变的引用计数未改变weak_ptr wp(p第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针2023/12/2243、weak_ptrv由于对象可能不存在,我们不能使用由于对象可能不存在,我们不能使用weak_ptr直接访直接访问对象,而必须调用问对象,而必须调用lock()。此函数检查。此函数检查weak_ptr指向指向的对象是否存在。如果存在,的对象是否存在。如果存在,lock则返回一个指向共享则返回一个指向共享对象的对象

24、的shared_ptr,同时该对象的引用计数会增加。,同时该对象的引用计数会增加。if(shared_ptr np=wp.lock()vshared_ptr智能指针最大的一个陷阱是循环引用,循智能指针最大的一个陷阱是循环引用,循环引用会导致内存泄漏。解决方法是改用环引用会导致内存泄漏。解决方法是改用weak_ptr。第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针2023/12/2253、weak_ptr第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针【例3-16】shared_ptr智能指针循环引用问题。#include#include using nam

25、espace std;struct Node int _data;shared_ptr next;shared_ptr prev;int main()shared_ptr sp1(new Node);shared_ptr sp2(new Node);sp1-next=sp2;sp2-prev=sp1;return 0;2023/12/2264、智能指针和动态数组、智能指针和动态数组v标准库提供了一个可以管理标准库提供了一个可以管理new分配数组的分配数组的unique_ptr版本。为了用一个版本。为了用一个unique_ptr管理动态数组,管理动态数组,我们必须在对象类型后面跟一对方括号。我们

26、必须在对象类型后面跟一对方括号。unique_ptr up(new int10);up.release();/自动用自动用delete 销毁其指针销毁其指针v当当unique_ptr指向数组时,我们不能使用点和箭头运指向数组时,我们不能使用点和箭头运算符,而是用下标来访问数组中的元素:算符,而是用下标来访问数组中的元素:for(size_t i=0;i!=10;+i)upi=i;/为每个元素赋予一个新值为每个元素赋予一个新值第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针2023/12/2274、智能指针和动态数组、智能指针和动态数组第第3章章 类和对象类和对象-动态内存与智

27、能指针动态内存与智能指针unique_ptr uu指指向向一一个个动动态态分分配配的的数数组组,数数组组元素类型为元素类型为Tunique_ptr u(p)u指指向向内内置置指指针针p所所指指向向的的动动态态分分配配的数组,的数组,p必须能转换为类型必须能转换为类型T*ui返返回回u拥拥有有的的数数组组中中位位置置i处处的的对对象象,u必须指向一个数组必须指向一个数组指向数组的unique_ptr支持的操作见表3-5。表3-5 指向数组的unique_ptr2023/12/2284、智能指针和动态数组、智能指针和动态数组v与与unique_ptr不同,不同,shared_ptr不直接支持管理动

28、态不直接支持管理动态数组,如果希望使用数组,如果希望使用shared_ptr管理一个数组必须提供管理一个数组必须提供一个自定义的删除器:一个自定义的删除器:share_ptr sp(new int10,(int*p)delete p;);/这里使用了这里使用了lambda表达式,详见表达式,详见11.5.5节节sp.reset();/使用我们提供的使用我们提供的lambda释放数组,它使释放数组,它使用用delete for(size_t i=0;i!=10;+i)*(sp.get()+i)=i;/由于由于shared_ptr不直接支持不直接支持动态数组,所以我们不能用下标直接访问元素动态数组,所以我们不能用下标直接访问元素第第3章章 类和对象类和对象-动态内存与智能指针动态内存与智能指针2023/12/229


注意事项

本文(《面向对象程序设计C++》课件1第3章 类和对象-动态内存与智能指针.ppt)为本站会员(bubibi)主动上传,文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知文库网(点击联系客服),我们立即给予删除!




关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

文库网用户QQ群:731843829  微博官方号:文库网官方   知乎号:文库网

Copyright© 2025 文库网 wenkunet.com 网站版权所有世界地图

经营许可证编号:粤ICP备2021046453号   营业执照商标

1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png 10.png