C++进阶--RAII 资源获取即初始化
//############################################################################
/* 资源获取即是初始化 (RAII)
*
* 使用对象来管理资源: (利用栈回退时一定会释放栈上对象的机制)
* 内存,硬件设备,网络句柄等
*/
Mutex_t mu = MUTEX_INITIALIZER;
void functionA()
{
Mutex_lock( &mu );
... // 做一系列事情
Mutex_unlock( &mu ); // 是否一定会被执行
}
/*
* 解决方法:
*/
class Lock {
privat:
Mutext_t* m_pm;
public:
explicit Lock(Mutex_t *pm) { Mutex_lock(pm); m_pm = pm;};
~Lock() { Mutex_unlock(m_pm); };
}
void functionA()
{
Lock mylock(&mu);
... // 做一系列事情
} // mutex总是会被释放,当myloack对象从栈上被销毁的时候
/* 结论:
*
* 在异常抛出后唯一保证会被执行的代码是
* 栈上对象的析构函数
*
* 所以资源管理要和合适的对象生命周期结合在一起
* 从而达到自动去分配和回收的目的
*/
/* Note 1:
* 另一个RAII的例子: tr1:shared_ptr
*/
int function_A() {
std::tr1::shared_ptr<dog> pd(new dog());
...
} // 当pd走出作用域时dog会被销毁 (没有指针指向pd).
// Note 2:
// 另一个例子:
class dog;
class Trick;
void train(tr1::shared_ptr<dog> pd, Trick dogtrick);
Trick getTrick();
int main() {
// tr1::shared_ptr<dog> pd(new dog());
train(tr1::shared_ptr<dog> pd(new dog()), getTrick());
}
//问题: 上面代码有什么问题?
// 参数传递的操作顺序由编译器决定
// 如果train()函数的参数传递按如下顺序进行会怎么样:
// 1. new dog();
// 2. getTrick();
// 3. construct tr1::shared_ptr<dog>.
// 第2步如果抛出异常,内存泄漏
// 结论:不要将对象存到共享指针的操作跟其他声明混到一起
/* Note 3:
如果资源的管理对象被拷贝会怎样?
*/
Lock L1(&mu);
Lock L2(L1);
/* Solution 1:
* 禁止拷贝. 见【不让编译器生成类函数】
*/
/* Solution 2:
* 使用tr1::shared_ptr对资源进行引用计数
*/
template<class Other, class D> shared_ptr(Other * ptr, D deleter);
// D的默认值是"delete":
std::tr1::shared_ptr<dog> pd(new dog());
class Lock {
private:
std::tr1::shared_ptr<Mutex_t> pMutex;
public:
explicit Lock(Mutex_t *pm):pMutex(pm, Mutex_unlock) {
Mutex_lock(pm);
// The second parameter of shared_ptr constructor is "deleter" function.
};
}
}
Lock L1(&mu);
Lock L2(L1);
C++进阶--RAII 资源获取即初始化的更多相关文章
- RAII(Resource Acquisition Is Initialization)资源获得式初始化
当在编写代码中用到异常,非常重要的一点是:“如果异常发生,程序占用的资源都被正确地清理了吗?” 大多数情况下不用担心,但是在构造函数里有一个特殊的问题:如果一个对象的构造函数在执行过程中抛出异常,那么 ...
- Java并发包源码学习系列:CLH同步队列及同步资源获取与释放
目录 本篇学习目标 CLH队列的结构 资源获取 入队Node addWaiter(Node mode) 不断尝试Node enq(final Node node) boolean acquireQue ...
- SpringMVC核心——参数获取与Servlet资源获取问题
一.SpringMVC 使用 @PathVariable.@RequestParam.@RequestHeader.@CookieValue 等来解决参数获取问题. 1. @PathVariable: ...
- 关于UI资源获取资源的好的网站
前言:和我一样喜欢UI的一定喜欢这里的内容. 下面是关于sketch资源获取网页,点击图片就能进入: 连接是:https://github.com/JakeLin 居然意外百度到Sketch中国,还提 ...
- js进阶 12-6 如何获取正在发生事件的名字和是哪个元素在发生事件
js进阶 12-6 如何获取正在发生事件的名字和是哪个元素在发生事件 一.总结 一句话总结:event.type 描述事件的类型. event.target 触发该事件的 DOM 元素. ...
- 关于资源获取(请把https改为http)
所有demo以及资源获取,请把https改为http.
- RALL资源获取初始化,删除器
body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...
- [转]抢先Mark!微信公众平台开发进阶篇资源集锦
FROM : http://www.csdn.net/article/2014-08-01/2820986 由CSDN和<程序员>杂志联合主办的 2014年微信开发者大会 将于8月23日在 ...
- Spring进阶教程之在ApplicationContext初始化完成后重定义Bean
前言 很久没有写博客了,也是两个原因:一是自己觉得一直在班门弄斧,其实自己没什么技术可言:二是很多朋友的问题实际上可以自行解决,我经常觉得不该我来过问,或者是有时候我认为技术还得靠自己钻研,我一两句话 ...
随机推荐
- [LeetCode&Python] Problem 350. Intersection of Two Arrays II
Given two arrays, write a function to compute their intersection. Example 1: Input: nums1 = [1,2,2,1 ...
- this语句的用法第一、二点
1.this是js的一个关键字,指定一个对象然后去代替他. 函数内的this和函数外的this,函数内的this指向行为发生的主体.函数外的this都指向window没有意思. 例题: functio ...
- mysql 查询进程和关闭进程
1.查询某一进程PID号 tasklist |findstr mysqld 2.关闭某一进程 taskkill /F /PID XXXX 3.制作 windows + r键输入services.msc ...
- 基本数据类型,数字int字符串str
基本数据类型 数字 int 字符串 str 布尔值 bool 列表 list 字典 dict 元组 tuple(待续...) 整数 int - 创建 a = 123 a = int(123) - 转换 ...
- python------模块定义、导入、优化 ------->re模块
该部分内容引用自:http://www.cnblogs.com/alex3714/articles/5161349.html 谢谢原博主的文章,只是自己学习,无其他使用. re模块 常用正则表达式符号 ...
- 【HAOI2011】problem a
又看题解了,这样下去要跪啊QAQ 原题: 一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低.”问最少有几个人没有说真话(可能有相同的分数) 1≤n≤100000 0≤ ...
- LG5056 【模板】插头dp
题意 题目背景 ural 1519 陈丹琦<基于连通性状态压缩的动态规划问题>中的例题 题目描述 给出n*m的方格,有些格子不能铺线,其它格子必须铺,形成一个闭合回路.问有多少种铺法? 输 ...
- day29akka
PS:AKKA之前要实现并发编程,通常要借用netty框架,现在如果又要高并发又要分布式就使用akka框架这个akka在客户端和服务端每一端都相当于一个actor,尤其是服务端需要一个总管进行管理 P ...
- 使用mongoose连接mongodb(转载文章)
mongodb数据库 MongoDB是一个高效的基于分布式文件存储的数据库,将数据存储为一个文档,数据结构由键值(key=>value)对组成.MongoDB 文档类似于 JSON 对象.字段值 ...
- VM安装系统时提示硬件不支持(unsupported hardware detected)
修改一下虚拟机配置,把CD/DVD中使用的autoinst.iso替换成需要安装的系统镜像文件 然而,后面发现还是会报这个错,不过,却可以正常安装下去.但是如果不修改这里的话,安装系统时会出错