《Effective C++》学习笔记条款13 以对象管理资源
例:
voidf()
{
Investment *pInv = createInvestment();
... //这里存在诸多“不定因素”,可能造成delete pInv;得不到执行,这可能就存在潜在的内存泄露。
delete pInv;
}
解决方法:把资源放进对象内,我们便可依赖C++的“析构函数自动调用机制”确保资源被释放。
许多资源被动态分配于堆内而后被用于单一区块或函数内。它们应该在控制流离开那个区块或函数时被释放。标准
程序库提供的auto_ptr正是针对这种形势而设计的特制产品。auto_ptr是个“类指针对象”,也就是所谓的“智能指针”,
其析构函数自动对其所指对象调用delete。
void f()
{
std::auto_ptr<Investment> pInv(createInvestment());
...
} //函数退出,auto_ptr调用析构函数自动调用delete,删除pInv;无需显示调用delete。
“以对象管理资源”的两个关键想法:
- 获得资源后立刻放进管理对象内(如auto_ptr)。每一笔资源都在获得的同时立刻被放进管理对象中。“资源取得时机便是初始化时机”(Resource Acquisition Is Initialization;RAII)。
- 管理对象运用析构函数确保资源被释放。即一旦对象被销毁,其析构函数被自动调用来释放资源。
由于auto_ptr被销毁时会自动删除它所指之物,所以不能让多个auto_ptr同时指向同一对象。所以auto_ptr若通
过copying函数复制它们,它们会变成NULL,而复制所得的指针将取得资源的唯一拥有权!
看下面例子:
std::auto_ptr<Investment> pInv1(createInvestment()); //pInv1指向createInvestment()返回物;
std::auto_ptr<Investment>pInv2(pInv1); //现在pInv2指向对象,而pInv1被设为NULL;
pInv1 = pInv2; //现在pInv1指向对象,而pIn2被设为NULL;
受auto_ptr管理的资源必须绝对没有一个以上的auto_ptr同时指向它。即“有你没我,有我没你”。
auto_ptr的替代方案是“引用计数型智能指针”(reference-counting smart pointer;SCSP)、它可以持续跟踪共有
多少对象指向某笔资源,并在无人指向它时自动删除该资源。
TR1的tr1::shared_ptr就是一个"引用计数型智能指针"。
void f()
{
...
std::tr1::shared_ptr<Investment> pInv1(createInvestment()); //pInv1指向createInvestment()返回物;
std::tr1::shared_ptr<Investment> pInv2(pInv1); //pInv1,pInv2指向同一个对象;
pInv1 = pInv2; //同上,无变化
...
} //函数退出,pInv1,pInv2被销毁,它们所指的对象也竟被自动释放。
auto_ptr和tr1::shared_ptr都在其析构函数内做delete而不是delete[],也就意味着在动态分配而得的数组身上使
用auto_ptr或tr1::shared_ptr是个潜在危险,资源得不到释放。也许boost::scoped_array和boost::shared_array能提供
帮助。还有,vector和string几乎总是可以取代动态分配而得的数组。
请记住:
- 为防止资源泄漏,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放资源。
- 两个常被使用的RAII类分别是auto_ptr和tr1::shared_ptr。后者通常是较佳选择,因为其拷贝行为比较直观。若选择auto_ptr,复制动作会使他(被复制物)指向NULL。
《Effective C++》学习笔记条款13 以对象管理资源的更多相关文章
- effective C++ 读书笔记 条款14 以对象管理资源
如果我们使用一个投资行为的程序库: #include "stdafx.h" #include <iostream> #include <memory> us ...
- Effective C++(13) 用对象管理资源
问题聚焦: 从这条准则开始,都是关于资源管理的. 资源,一旦用了它,将来必须还给系统. 本条准则,基于对象的资源管理办法,建立在C++的构造函数,析构函数和拷贝函数(拷贝构造函数和重载赋值操作符)的基 ...
- Effective C++学习笔记 条款04:确定对象被使用前已先被初始化
一.为内置类型对象进行手工初始化,因为C++不保证初始化它们. 二.对象初始化数据成员是在进入构造函数用户编写代码前完成,要想对数据成员指定初始化值,那就必须使用初始化列表. class A { pu ...
- Effective C++学习笔记 条款07:为多态基类声明virtual析构函数
一.C++明确指出:当derived class对象经由一个base class指针被删除,而该base class带着一个non-virtual析构函数,其结果未定义——实际执行时通常发生的是对象的 ...
- Effective C++学习笔记 条款02:尽量以const,enum,inline替换 #define
尽量使用const替换 #define定义常量的原因: #define 不被视为语言的一部分 宏定义的常量,预处理器只是盲目的将宏名称替换为其的常量值,导致目标码中出现多分对应的常量,而const定义 ...
- Effective Java学习笔记--创建和销毁对象
创建和销毁对象 一.静态工厂方法代替构造器 静态工厂方法的优缺点 优点: 1.可以自定义名称(可以将功能表述的更加清晰) 2.不必每次调用都创建新的对象(同一对象重复使用) 3.返回的类型可以是原返回 ...
- Effective C++学习笔记 条款06:如不想使用编译器自动生成的函数,就该明确拒绝
一.为驳回编译器自动提供的机能,可将相应成员函数声明为private并且不予实现.(如果你仅仅是自己不实现的话,编译器会帮你实现) 如: class A { public: A(const strin ...
- Effective C++学习笔记 条款05:了解C++默默编写并调用的哪些函数
一.如果用户没有提供构造函数.copy构造函数.copy assignment操作符和析构函数,当且仅当这些函数被需要的时候,编译器才会帮你创建出来.编译器生成的这些函数都是public且inline ...
- Linux学习笔记(13)权限管理
1 ACL权限 (1)简介和开启方式 ACL(Access Control List)权限的目的是在提供传统的owner.group.others的read.write.execute权限之外的局部权 ...
随机推荐
- JavaScript中将JSON的字符串解析成JSON数据格式
1.一种为使用eval()函数 var jsonObj=eval("("+data+")"); 2.使用Function对象来进行返回解析 var jsonst ...
- java 文件类操作(转载)
11.3 I/O类使用 由于在IO操作中,需要使用的数据源有很多,作为一个IO技术的初学者,从读写文件开始学习IO技术是一个比较好的选择.因为文件是一种常见的数据源,而且读写文件也是程序员进行IO编程 ...
- 第 14 章 迭代器模式【Iterator Pattern】
以下内容出自:<<24种设计模式介绍与6大设计原则>> 周五下午,我正在看技术网站,第六感官发觉有人在身后,扭头一看,我C,老大站在背后,赶忙站起来, “王经理,你找我?” 我 ...
- 【POJ 1830】 开关问题 (高斯消元)
开关问题 Description 有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为 ...
- 使用jdk生成证书以及把证书导入到jdk中
证书对于实现此单点登录非常之重要,证书是服务器端和客户端安全通信的凭证,本教程只是演示,所有用了JDK自带的证书生成工具keytool.当然在实际项目中你可以到专门的证书认证中心购买证书. 中文官方网 ...
- 李洪强iOS开发-网络新闻获取数据思路回顾
李洪强iOS开发-网络新闻获取数据思路回顾 01 创建一个继承自AFHTTPSessionManager的工具类:LHQNetworkTool 用来发送网络请求获取数据 1.1 定义类方法返回单例对 ...
- TF卡的Class4/Class6/Class10
TF卡全称TransFlash卡,即T-Flash又称MicroSD,随设备微型化的需要,TF卡用途越来越广,速度也越来越快,从最初的Class2早已发展到目前主流的Class10,TF卡体积为15m ...
- Win7新建ftp快捷方式(原XP网上邻居中客户端图标)
2014-6-2 XP逐渐隐退,新机器一般都是Win7或者Win8了.有很多朋友反映在这两个新系统中找不到类似XP网上邻居中的ftp链接图标.故稍微研究了下,以Win7为例,总结如下. 1.骨灰级 ...
- UNion ALL 和 UNION 的区别
UNION: 指定合并多个结果集并将其作为单个结果集返回.ALL: 将全部行并入结果中.其中包括重复行.如果未指定该参数,则删除重复行.
- 门面模式 到 socket
http://www.cnblogs.com/java-my-life/archive/2012/05/02/2478101.html 1.门面模式定义: 门面模式是对象的结构模式,外部与一个子系统的 ...