Effect C++ 学习笔记三:资源管理
资源:内存,文件描述器,互斥锁,图形界面的字体和笔刷,数据库链接,socket等。
十三:Use objects to manage resources. 以对象管理资源
class Investment{...};
Investment* createInvestment();
void f()
{
Investment* pInv = createInvestment();
//...
delete pInv;
}
为了确保createInvestment返回的资源总是被释放,我们需要将资源放进对象内,当控制流离开f,该对象的析构函数会自动释放那些资源。把资源放进对象内,我们便可依赖c++的“析构函数自动调用机制”确保资源被释放。
改写f():
void f()
{
std::auto_ptr<Investment> pInv(createInvestment());
...
//调用factory函数 一如以往地使用pInv 经由auto_ptr地析构函数自动删除pInv
}
注:获得资源后立刻放进管理对象内。 管理对象运用析构函数确保资源被释放。
然而auto_ptr的所有权模型表明同时只能有一个auto指针指向对象。
std::auto_ptr<Investment> pInv1(createInvestment());//pInv1指向createInvestment返回物std::auto_ptr<Investment> pInv2(pInv1);//现在pInv2指向对象 pInv1被设为nullpInv1 = pInv2;//现在pInv1指向对象,pInv2被设为Null
可以用引用计数模型指针替代它。
总结:
为了防止资源泄露,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放资源。
两个常被使用的RAII classes分别是tr1::shared_ptr和auto_ptr。前者通常时较佳选择,因为其copy行为比较直观。若选择
auto_ptr,复制动作会使它指向null。
十四:Think carefully about copying behaviour in resource-managing classes。在资源管理类中小心coping行为
void lock(Mutex* pm);
void unlock(Mutex* pm);class Lock
{
public:explicit Lock(Mutex* pm):mutexPtr(pm){lock(mutexPtr);//获得资源}~Lock() { unlock(mutexPtr); }//释放资源
private:Mutex *mutexPtr;
};//客户对Lock的用法符合RAII方式Mutex m; //定义所需的互斥器
...
{ //建立一个区块用来定义critical sectionLock m1(&m);//锁定互斥器... //执行critical section内的操作
} //在区块最末尾, 自动解除互斥器锁定
如果复制了Lock对象。
Lock m11(&m); //锁定m
Lock m12(m11); //复制
当一个RAII对象被复制,我们可以选择
1.禁止复制。 见前 private copying
2.引用计数。
我们可以改变mutexPtr的类型,用shared_ptr封装起来,但shared_ptr的缺省行为是“当引用计数为0时删除其所指物。”
我们可以给shared_ptr指定一个删除器(function),当引用计数为0时被调用。
见例子:
class Lock
{
public:explicit Lock(Mutex* pm):mutexPtr(pm, unlock){lock(mutexPtr.get());}
private:std::tr1::shared_ptr<Mutex> mutexPtr;
};
3.复制底部资源。进行deep copy.
4.转移底部资源的所有权。
总结:
1.复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为。
2.普遍而常见的RAII class copying 行为是:抑制 copying 引用计数。
十五:Provide access to raw resources in resource-managing classes.在资源管理类中提供对原始资源的访问
例如tr1::shared_ptr和auto_ptr提供一个get成员函数,用来执行显式转换,它会返回智能指针内部的原始指针
注:APIs往往要求访问原始资源,所以每一个RAII class应该提供一个“取得其所管理之资源”的方法。
对原始资源的访问可能由显式转换或隐式转换。一般来说显示转换比较安全,但隐式转换对客户比较方便。
十六:Use the same form in corresponding uses of new and delete 成对使用new和delete时要采用相同形式
std::string* stringArray = new std::string[100];delete stringArray;
使用new 时 1.分配内存 2.构造函数被调用 使用delete时 1.析构函数被调用 2.内存被释放
delete执行时需要知道删除的那个指针所指的是单一对象或对象数组,决定它执行析构的数量。
通过显式声明 delete[]告诉程序释放的是一个数组结构。
结论:
new[] 和 delete[]对应
new和delete对应。
需要注意的是typedef 需要清楚以何种方式释放。
十七:Store newed objects in smart pointers in standalone statements.以独立语句将newed对象置入智能指针。
考虑一个例子:
int priority();
void processWidget(std::tr1::shared_ptr<Widget> pw, int priority);proccessWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());
考虑这个调用,
编译器可能的操作顺序:
1.调用priority
2.执行"new Widget"
3.调用tr1::shared_ptr构造函数
也有可能是这样的操作顺序:
1.执行 "new Widget"
2.调用 priority
3.调用 tr1::shared_ptr 构造函数
在这种调用顺序下,如果对priority的调用导致异常,会导致资源泄露。
为了避免这个风险,考虑:
std::tr1::shared_ptr<Widget> pw(new Widget);processWidget(pw, PRIORITY());
这样写可以规定顺序,防止风险。
总结:
以独立语句将newed对象存储于智能指针内。
Effect C++ 学习笔记三:资源管理相关推荐
- J2EE学习笔记三:EJB基础概念和知识 收藏
J2EE学习笔记三:EJB基础概念和知识 收藏 EJB正是J2EE的旗舰技术,因此俺直接跳到这一章来了,前面的几章都是讲Servlet和JSP以及JDBC的,俺都懂一些.那么EJB和通常我们所说的Ja ...
- tensorflow学习笔记(三十二):conv2d_transpose (解卷积)
tensorflow学习笔记(三十二):conv2d_transpose ("解卷积") deconv解卷积,实际是叫做conv_transpose, conv_transpose ...
- Ethernet/IP 学习笔记三
Ethernet/IP 学习笔记三 原文为硕士论文: 工业以太网Ethernet/IP扫描器的研发 知网网址: http://kns.cnki.net/KCMS/detail/detail.aspx? ...
- iView学习笔记(三):表格搜索,过滤及隐藏列操作
iView学习笔记(三):表格搜索,过滤及隐藏某列操作 1.后端准备工作 环境说明 python版本:3.6.6 Django版本:1.11.8 数据库:MariaDB 5.5.60 新建Django ...
- 吴恩达《机器学习》学习笔记三——多变量线性回归
吴恩达<机器学习>学习笔记三--多变量线性回归 一. 多元线性回归问题介绍 1.一些定义 2.假设函数 二. 多元梯度下降法 1. 梯度下降法实用技巧:特征缩放 2. 梯度下降法的学习率 ...
- Python基础学习笔记三
Python基础学习笔记三 print和import print可以用,分割变量来输出 import copy import copy as co from copy import deepcopy ...
- Mr.J-- jQuery学习笔记(三十二)--jQuery属性操作源码封装
扫码看专栏 jQuery的优点 jquery是JavaScript库,能够极大地简化JavaScript编程,能够更方便的处理DOM操作和进行Ajax交互 1.轻量级 JQuery非常轻巧 2.强大的 ...
- MYSQL学习笔记三:日期和时间函数
MYSQL学习笔记三:日期和时间函数 1. 获取当前日期的函数和获取当前时间的函数 /*获取当前日期的函数和获取当前时间的函数.将日期以'YYYY-MM-DD'或者'YYYYMMDD'格式返回 */ ...
- ROS学习笔记三:创建ROS软件包
,# ROS学习笔记三:创建ROS软件包 catkin软件包的组成 一个软件包必须满足如下条件才能被称之为catkin软件包: 这个软件包必须包含一个catkin编译文件package.xml(man ...
最新文章
- Linux那些事儿之我是Sysfs(6)文件系统
- css3 自定义滚动条样式
- Linux系统之创建逻辑卷
- 图像浏览界面缩放和平移操作的实现
- hook xposed 自定义类_【开始学习React Hook(1)】Hook之useState
- 中航工业集团金网络(北京)电子商务有限公司副总经理刘正珩:航空“智”造的供应链支撑平台...
- C#学习笔记(十四):StatusBar控件
- RSA算法与DSA算法的区别
- 使用Idea简单搭建springcloud项目
- 如何合并mysql中的行_如何在MySQL中合并行?
- c++ memset 语言_C/C++ 中memset() 函数详解及其作用介绍
- 灰度共生矩阵(Gray Level Co-occurrence Matrix,GLCM)
- 基于Spring Boot的简易版新闻管理系统
- opera官方教程 档案
- ALFA深度学习外观检测自学习人工智能软件
- 智能卡卡发卡流程(收藏3)
- 回顾2020,展望2021
- SQL(10)_PRIMARY KEY 约束
- php接入外汇购物,兑换难!这些外币最好别带回国
- 短域名Andy.ge 安迪哥的启用
热门文章
- 事后控制不如事中控制,事中控制不如事前控制
- iOS企业版app部署到自己的服务器
- SSDP(简单服务发现协议)
- systemUI 学习记录1
- NanoPC-T4|Android-Q 色温调节
- [C语言]Pow函数的实现
- 【iOS】AVPlayer 视频播放
- 倍福触摸屏维修倍福工控机维修CP3916-0010详解
- 作为一个程序员,你是怎么管理文档资料的?我这个方法特别方便
- 辅修计算机编程,求帮忙~计算机C语言的编程题!大学选的辅修课没去过,要考试了不会? 爱问知识人...