欢迎来到天天文库
浏览记录
ID:22442016
大小:184.23 KB
页数:16页
时间:2018-10-29
《寻找理想的智能指针-c资源管理综述》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、寻找理想的智能指针一04■资源管理综述摘要:C++中的资源管理历来是比较令人头痛的问题,随着C++OX标准的酝酿,这一问题再次引起了人们的关注。本文将和您一道对C++中的资源管理方式进行回顾,分析与展望,并探讨理想的智能指针应该满足哪些条件。C的时代C语言中用指针来表示对资源的引用,这里的资源包括动态内存(堆内存)及同步对象,文件对象等由操作系统抽象出来的对象。有的操作系统中用句柄(handle)表示对这类对象的引用,其语义与指针是相同的。下文中提到的对象如不加说明,一般均指资源对象。一个用于引用资源的指针(其它的指针,比如指向局
2、部变量的指针或指向指针的指针,这里不予研究)从产生到消亡的整个生存期中可能处于以下四种状态:1空指针所有指针刚产生时的初始状态都是空指针。C语言屮作为局部变量的指针初始状态下包含的值是随机的,但它没有额外的语义,其实质还是空指针,程序员应该显式将其初始化为空,以防止误用。2.强指针强指针是指向某一对象并对其拥有所有权的指针。资源产生后其引用需保存在一个指针中,这个指针这时就是强指针,执行下面的代码后:ObjectA*pObj1=NULL;pObjl=newObjectA;pObjl就成为强指针。资源的所有权可以转移,其表现形式为指
3、针赋值。在强指针的生存期结束之前,它所指向的资源需要被释放,否则会产生资源泄漏。3.弱指针仅指向对象但不包含所有权的指针是弱指针。代码中如果要在多处引用同一个对象就要用到弱指针。执行了下面这句代码之后:ObjectA*pObj2=pObjl;PObj2是一个弱指针吗?答案是无法确定。强指针和弱指针的语义在字面上(语法上)无法表达,全靠程序员认定和跟踪,这显然是难以把握并且极易出错的。这句代码可以这样分析:如果认定PObj2是弱指针,则pObjl仍是强指针;如果认定这是一个资源所有权的转移过程,则pObj2取得所有权,成为强指针,p
4、Objl变成了弱指针。在某一时间点,指向一个对象的强指针只可能有一个,而指向这一对象的弱指针可以有无数个。4.妍旨#也叫悬空指针。资源被释放之后,所冇仍指向这•一对象的指针都成为野指针。执行了这句代码之后:deletepObj1;pObjl和pObj2都变成野指针,可以将它们清空:pObj1=NULL;pObj2=NULL;野指针成为空指针,完成了一个状态循环。资源释放后如果继续使用野指针或再次释放资源都是严重的错误,很可能导致内存非法访问。指针的四种状态和互间的转换关系可以用图1表示。图1.指针状态转换图其中“②强制清空”是不允
5、许的,会造成资源泄漏。对照图1总结一下编程屮可能出错的情况:指针以强指针的状态消亡或被强制清空都会使它指向的对象永远无法访问,引起内存泄漏,所以一定不要忘记释放资源;强指针转化为野指针后不能再引用,应马上清空,防止以后误用;而弱指针转化为野指针的情况比较难以跟踪和觉察,因为资源是在别处释放的(强指针状态下才能释放资源),只有从更大的范围控制程序流程才有望避免出错。从以上分析可以看出,指向资源的指针状态变化很复杂,大量的语义细节需要程序员跟踪和控制,难度很大,一不留神就会出错,这也就是C语言中有名的“内存管理hell”出现的原因。问
6、题还不止于此,强弱指针的语义差别造成了模块与模块之间耦合度的增大。简单的说就是模块接口中涉及的资源由谁分配由谁释放的问题必须跨越模块协调解决。举个例子,在C语言库函数的文档中随便找一个涉及字符串的函数的说明,一般都会有一段文字叮嘱我们调用前要分配多大的内存或者返回的内存要由调用者释放等等。这种耦合对软件系统的设计、实现及维护都带来了不利影响,是制约C语言开发效率提高的重要因素之一。C++社群的探索资源管理问题成为后来的程序设计语言需重点解决的一个问题。在面向对象的语言中,自动化的资源管理主耍有两种解决方案,第一种是以Eiffel和
7、Java为代表的GC(GarbageCollection)方案。C++因为要兼容C语言,釆用GC有一定网难,由此引入了第二种解决方案:智能指针。智能指针是一个辅助类,它包含了普通指针用于资源管理时的功能和语义,并尽量保持指针的接口不变,也就是说,使用起来和原来的指针差不多,最重要的是,它增加了自动管理资源的功能,这才是它之所以被称为“智能”指针的原因。实际上我们是把资源管理的职责从客户代码中移到了智能指针类中,见图2。客户代码(资源管理)指针(引用资源)客户代码智能指针(引用资源+资源管理)资源a.C语言中资源b.引入智能指针后图
8、2.资源管理职责变化示意图智能指针在即将超出作用域时会自动释放所拥有的资源,指向新的资源以前也会把原来拥有的资源先释放掉,用户代码中不需耍再考虑资源管理,可以简化用户代码并防止资源泄漏:智能指针释放资源后会自动罝自身状态为空,不会出现野指针状态,能
此文档下载收益归作者所有