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
前言 很久没有写博客了,也是两个原因:一是自己觉得一直在班门弄斧,其实自己没什么技术可言:二是很多朋友的问题实际上可以自行解决,我经常觉得不该我来过问,或者是有时候我认为技术还得靠自己钻研,我一两句话 ...
随机推荐
- 九度OJ1122题-吃巧克力
题目1122:吃糖果 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2453 解决:1957 题目描述: 名名的妈妈从外地出差回来,带了一盒好吃又精美的巧克力给名名(盒内共有 N 块巧克力 ...
- html播放音乐
如何在网站网页中添加音乐代码 告诉你多种格式文件的详细使用代码. width_num——指定一个作为宽度的数字: height_num——指定一个作为高度的数字: 1.mp3 ...
- 区块链与Git版本工具的比较
区块链与Git版本工具的比较 来源:http://www.jianshu.com/p/b96b98983df6 作者: 梁波林 相同点: 1. 分布式存储方案 2. 链式数据 3. 去中心化 4. ...
- Gym-101673 :East Central North America Regional Contest (ECNA 2017)(寒假自训第8场)
A .Abstract Art 题意:求多个多边形的面积并. 思路:模板题. #include<bits/stdc++.h> using namespace std; typedef lo ...
- lesson3 overfitting -fastai
VGG:3*3Imagenet:7*7,9*9论文中证明3*3更胜一筹,但是用多少并没有定论微调:删掉模型的中间只对最后一层微调:model.pop,就删掉了最后一层 如何决定训练多少层?:·看论文上 ...
- iptables filter表 案例、iptables nat表的路由功能 、端口映射
1.小案例 #!/bin/bashipt="/usr/sbin/iptables"$ipt -F$ipt -P INPUT DROP$ipt -P OUTPUT ACCEPT$ip ...
- JavaSE笔记
this关键字 哪个对象调用方法,方法定义中的this即为该对象的引用! static关键字 使用static声名的成员变量为静态成员变量,在第一次使用的时候被初始化,static成员变量只有一份 使 ...
- Redis(二)持久化
Redis持久化,分为RDB方式和AOF方式,它们可以单独使用,也可以混用.Redis默认的是使用RDB方式. 一.RDB方式 1.触发快照的方式 RDB方式是在指定时间间隔内某一时间点的数据集快照. ...
- CentOS下如何根据Dump文件分析线上问题
https://blog.csdn.net/lixin03080/article/details/79711296 一.保存现场 1.记录系统整体资源使用情况,进程信息.线程信息 top -b -n ...
- Android USB gadget configfs学习笔记总结
1.一个config_item 是通过显式用户空间mkdir操作创建的,通过rmdir销毁.属性(文件)在mkdir之后出现,可以通过read和write读取或修改属性文件.与sysfs一样,read ...