/*条款29 为“异常安全”而努力是值得的*/
#include<iostream>
#include<memory>
using namespace std;
struct PMImpl{
shared_ptr<Image>bgImage;
int imagechanges;
};
class Mutex{};
void lock(Mutex*mutex){
cout << "locked" << endl;
}
void unlock(Mutex*mutex){
cout << "unlock" << endl;
}
class Lock{
public:
explicit Lock(Mutex*pm) :mutexPtr(pm){
lock(mutexPtr);
}
~Lock(){
unlock(mutexPtr);
}
private:
Mutex*mutexPtr;
};
class Image{
public:
Image(istream&imgSrc){
}
};
class PrettyMenu{
public:
//...
void changeBackground(istream&imSrc);
private:
Mutex mutex;
//Image*bgImage;
//shared_ptr<Image>bgImage;//管理资源
shared_ptr<PMImpl> pImpl;
int imageChanges;
};
Image* gbImage = new Image(cin);
void PrettyMenu::changeBackground(istream&imgSrc){
/*lock(&mutex); //取得互斥器
delete gbImage;//摆脱旧的背景图像
bgImage = new Image(imgSrc);//安装新的背景图像
unlock(&mutex);//释放互斥器*/
Lock lk(&mutex);//条款14 改进1
++imageChanges;//修改图像变更次数
//bgImage.reset(new Image(imgSrc));//new的结果设定内部指针,这里有一好处是new申请成功才会被reset调用
shared_ptr<PMImpl>pNew(new PMImpl(*pImpl));
pNew->bgImage.reset(new Image(imgSrc));//修改副本
++pNew->imagechanges;
swap(pImpl, pNew); //swap 释放mutex
}
/*
异常安全的两个条件是:
1 不泄漏任何资源 。如果new Image(imgSrc)导致异常 ,unlock就不会调用 ,于是互斥器就永远被把持住了
2 不允许数据败坏。 如果new Image(imgSrc)导致异常,bgImage就是指向一个已被删除的对象
*/
/*
异常安全函数提供以下三个保证之一
1 基本承诺:如果异常被抛出,程序内的任何事物仍然保持有效状态
2 强烈保证:如果异常被抛出,程序状态不改变。例如调用这样的函数需要有这样的认知:如果函数成功,就是完全成功,如果函数失败,程序会回恢到“调用函数之前”的状态
3 不抛掷保证:承诺绝不抛出异常,因为它们总是能够未完成它们原先承诺的功能。
*/
/*copy and swap 策略:为你打算修改的对象(原件),做出一个副本(copy),然后在那副本身上做一切必要修改,若任何修改动作抛出异常,则原对象仍保持未改变状态,等所有改变成功后,再将修改过的那个副本和原对象在一个不抛出的异常操作中转换(swap)*/
/*一个软件系统要不就具备异常安全性,要不就全然不具备异常安全性,因为调用不具备异常安全性的函数有可能导致资源泄漏或数据结构败坏
总结:1 异常安全函数即使发生异常也不会泄漏资源或允许任何数据结构败坏,这样的函数区分 为三种可能的保证:基本型,强烈型,不抛异常型
2 “强烈保证”往往能够以copy and swap实现出来,但“强烈保证”并非对所有函数都有实现或具备现实意义
3 函数提供的“异常安全保证”通常最高只等于其所调用之各个函数的“异常安全保证”中的最弱者
*/
int main(){
system("pause");
return 0;
}
条款29 为“异常安全”而努力是值得的
最新推荐文章于 2020-05-16 09:09:56 发布