为了异常安全(swap,share_ptr)——Effecive C++
互斥锁:
假设我们要在多线程中实现背景图片的控制:
class PrettyMenu{
public:
……
void changeBackground(std::istream& imgSrc);//改变背景图片
……
private:
Mutex mutex; //互斥量
Image* bgImage; //当前背景图片
int imageChanges; //背景图片改变次数
};
void PrettyMenu::changeBackground(std::istream& imgSrc)
{
lock(&mutex);
delete bgImage;
++imageChanges;
bgImage=new Image(imgSrc);
unlock(&mutex);
}
但是上面这些会遇到两个问题:
- 如果 new Image(imgSrc)发生了异常,那么unlock就不会被执行,会被一直锁住
- 发生上面异常,imageChanges也被累加,但实际上新的图片没有被安装
对于第一个问题:
被及时释放的互斥锁:
share_ptr我们可以指定它的删除器,所以可以在删除器中释放互斥锁.
如此即使是发生了异常,互斥锁也能够被及时的释放。
class Lock{
public:
explicit Lock(Mutex* mu):mutexPtr(mu,unlock)//以某个Mutex初始化,unlock作为删除其
{
lock(mutexPtr);
}
private:
shared_prt<Mutex> mutexPtr;
};
如果通过一个Lock类,然后在析构函数阶段进行 unlock也可以避免这个问题。但是这样的类进行复制的时候
可能存在很多不合理的问题。
如果希望保存资源直到最后一个对象消失,并且在复制的时候是引用计数,可以使用上面这种情况。
对于第二个问题:
swap的 全or无:
struct PMImpl{
std::tr1::shared_ptr<Image> bgImage;
int imageChanges;
};
class PrettyMenu{
……
private:
Mutex mutex;
std::tr1::shared_ptr<PMImpl> pImpl;
};
void PrettyMenu::changeBackground(std::istream& imgSrc)
{
using std::swap;//**条款**25
Lock m1(&mutex);
std::tr1::shared_ptr<PMImpl> pNew(new PMImpl(*pImpl));
pNew->bgImage.reset(new Image(imgSrc));;//修改副本
++pNew->imageChanges;
swap(pImpl,pNew);
}
我们可以先弄一个副本,在进行完所有的操作之后,再与目标对象进行交换。
从而实现: 要不然就不处理,不然就全部处理完。
所以我们需要一个 不会抛出异常的swap操作。
参考:
《Effective C++》
为了异常安全(swap,share_ptr)——Effecive C++的更多相关文章
- 【25】考虑写出一个不抛异常的swap函数
1.swap交换对象值,std提供了实现方法模版的实现,它的实现是交换对象值. namespace std { template<typename T> void swap(T& ...
- [Effective C++ --025]考虑写出一个不抛异常的swap函数
引言 在我的上一篇博客中,讲述了swap函数. 原本swap只是STL的一部分,而后成为异常安全性编程的脊柱,以及用来处理自我赋值可能性. 一.swap函数 标准库的swap函数如下: namespa ...
- EC读书笔记系列之13:条款25 考虑写出一个不抛异常的swap函数
记住: ★当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定其不抛出异常 ★若你提供一个member swap,也该提供一个non-member swap来调用前者.对于cla ...
- Effective C++:条款25:考虑写出一个不抛异常的swap函数
(一) 缺省情况下swap动作可由标准程序库提供的swap算法完毕: namespace std { template<typename T> void swap(T& a, T& ...
- 考虑实现一个不抛异常的swap
Effective C++:参考自harttle land 类的swap实现与STL容器是一致的:提供swap成员函数, 并特化std::swap来调用那个成员函数. class Widget { p ...
- Effective C++ -----条款25:考虑写出一个不抛异常的swap函数
当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛出异常. 如果你提供一个member swap,也该提供一个non-member swap用来调用前者.对于cla ...
- 《Effective C++》item25:考虑写出一个不抛异常的swap函数
std::swap()是个很有用的函数,它可以用来交换两个变量的值,包括用户自定义的类型,只要类型支持copying操作,尤其是在STL中使用的很多,例如: int main(int argc, _T ...
- Effective C++ Item 25 考虑写出一个不抛异常的swap函数
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛 ...
- 不抛异常的swap函数
namespace AStuff{ template<typename T> class A { public: void swap(A *other) { using std::swap ...
随机推荐
- Beta Scrum Day 7
听说
- Alpha第八天
Alpha第八天 听说 031502543 周龙荣(队长) 031502615 李家鹏 031502632 伍晨薇 031502637 张柽 031502639 郑秦 1.前言 任务分配是VV.ZQ. ...
- C语言数据类型作业
一.PTA实验作业 题目1:7-4 打印菱形图案 1. 本题PTA提交列表 2. 设计思路 1.定义m,n(用于计算空格数,输出"* "数),i,j,k(用于循环) 2.输入n,并 ...
- 乘法表(24.9.2017) (WARNING!!!!!!!!!!!)
#include "stdio.h" main() { int i,j,result; printf("\n"); ;i<;i++) { ;j<;j ...
- JAVA中GridBagLayout布局管理器应用详解
很多情况下,我们已经不需要通过编写代码来实现一个应用程序的图形界面,而是通过强大的IDE工具通过拖拽辅以简单的事件处理代码即可很轻松的完成.但是我们不得不面对这样操作存在的一些问题,有时候我们希望能够 ...
- JAVA接口基础知识总结
1:是用关键字interface定义的. 2:接口中包含的成员,最常见的有全局常量.抽象方法. 注意:接口中的成员都有固定的修饰符. 成员变量:public static final 成员方法 ...
- new malloc和delete free 的区别
今天看了一个面试题:问new 和 malloc, delete 和 free 的区别,扭捏了半天,也没说完全:现总结如下: 1.先看看new 和 delete 看一个例子: <span styl ...
- 201421123042 《Java程序设计》第11周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 源代码阅读:多线程程序BounceThread 1.1 BallR ...
- JQuery 动态加载iframe.
html: <iframe id="ifm" style="width:inherit;height:inherit" runat="serve ...
- Spring源码情操陶冶#task:scheduled-tasks解析器
承接前文Spring源码情操陶冶#task:executor解析器,在前文基础上解析我们常用的spring中的定时任务的节点配置.备注:此文建立在spring的4.2.3.RELEASE版本 附例 S ...