为了异常安全(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 ...
随机推荐
- 201621123062《java程序设计》第七周作业总结
1. 本周学习总结 1.1 思维导图:Java图形界面总结 1.2 可选:使用常规方法总结其他上课内容. 1.布局管理器的具体使用方法 2.事件处理模型及其代码的编写 3.Swing中的常用组件 4. ...
- 团队开发---”我爱淘“校园二手书店 NABC分析
本项目特点之一:可预订 N:对于一些抢手的书可以提前预定,避免学生买不到书 A:网上下单,通过手机便捷购物 B:使得订书更加方便快捷 C:二手书摊.网上书店 团队成员:杨广鑫.郭健豪.李明.郑涛
- MySQL搭建主从数据库 实现读写分离
首先声明,实际生产中,网站为了提高用户体验,性能等,将数据库实现读写分离是有必要的,我们让主数据库去写入数据,然后当用户查询的时候,然后在从数据库读取数据,故能减轻数据库的压力,实现良好的用户体验! ...
- 学习less
什么是less?LESSCSS是一种动态样式语言,属于CSS预处理语言的一种,它使用类似CSS的语法,为CSS的赋予了动态语言的特性,如变量.继承.运算.函数等,更方便CSS的编写和维护. less哪 ...
- Mybatis-select-返回值类型错误理解
Mybatis :Cause: java.lang.UnsupportedOperationException异常: 今天在写一个练手项目,作为初学Mybatis的小白,想着这里findByEmp_i ...
- Win7添加php环境变量.
1) "我的电脑"右键"属性"->高级系统设置->环境变量->系统变量->Path->编辑 2) 将PHP的执行路径的目录&quo ...
- react-native-image-picker 运用launchCamera直接调取摄像头的缺陷及修复
在前几天用react-native进行android版本开发当中,用到了"react-native-image-picker"的插件:根据业务的需求:点击按钮-->直接调取摄 ...
- Spring Security 入门(1-7)Spring Security - Session管理
参考链接:https://xueliang.org/article/detail/20170302232815082 session 管理 Spring Security 通过 http 元素下的子元 ...
- O(logN)中logN的底数
转载:http://blog.csdn.net/jdbc/article/details/42173751 问题: 无论是计算机算法概论.还是数据结构书中, 关于算法的时间复杂度很多都用包含O(log ...
- Android 学习资料入门到精通(PDF集合)共54本
最近收集一些安卓入门到精通,包含游戏编程,网络编程,多媒体开发,需要学习朋友就下载保持下来,下载链接在最下面 下面是网盘内容 14天学会安卓开发_(完整版).pdf Android 4 游戏高级编程 ...