《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权限之外的局部权 ...
随机推荐
- Sass 编译的几种方法
常常有人会问,使用 Sass 进行开发,那么是不是直接通过“<link>”引用“.scss”或“.sass”文件呢? 那么这里告诉大家,在项目中还是引用“.css”文件,Sass 只不过是 ...
- appium的安装过程(图文界面)
资料来源:http://www.cnblogs.com/fnng/p/4560298.html 1.准备安装材料
- SortedList的用法
1.SortedList定义 System.Collections.SortedList类表示键/值对的集合,这些键值对按键排序并可按照键和索引访问.SortedList 在内部维护两个数组以存储列表 ...
- Computer Talker with C# z
Using the Code Add a textbox named 'txtWords' to a form. Add a button named 'btnSpeak' to a form. Ad ...
- CSS3 calc() 会计算的属性
calc是英文单词calculate(计算)的缩写,是css3的一个新增的功能,你可以使用calc()给元素的border.margin.pading.font-size和width等属性设置动态值. ...
- http://jinnianshilongnian.iteye.com/blog/1996071
http://jinnianshilongnian.iteye.com/blog/1996071 http://my.oschina.net/jkcui/blog/388400 http://tian ...
- 【Spring】Spring IOC原理及源码解析之scope=request、session
一.容器 1. 容器 抛出一个议点:BeanFactory是IOC容器,而ApplicationContex则是Spring容器. 什么是容器?Collection和Container这两个单词都有存 ...
- Android开源项目发现---GridView 篇(持续更新)
1. StaggeredGridView 允许非对齐行的GridView 类似Pinterest的瀑布流,并且跟ListView一样自带View缓存,继承自ViewGroup 项目地址:https:/ ...
- React入门1
React教程 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <t ...
- 【转】xcode APP 打包以及提交apple审核详细流程(新版本更新提交审核)
原文网址:http://blog.csdn.net/mad1989/article/details/8167529 最近项目到了最后的阶段,测试完一切ok后,准备打包以及提交,不料看到网上众教程,好多 ...