美文网首页
Effective c++ 学习笔记(item29)

Effective c++ 学习笔记(item29)

作者: 懒生活 | 来源:发表于2022-09-23 11:01 被阅读0次

努力写异常安全的代码

# 为什么绕不开异常

如果是从c转型到c++的,其实对异常会非常不适应,开发的代码往往是不考虑异常,异常来了,一路上行,不会被catch,直到系统硼溃。

如果用c++那么绕不开异常,new, delete, stl的容器都可能抛出异常。最多是你对所有的异常都不处理,但是异常已经在c++程序中不可避免了。

异常的目的。

当异常发生的时候,如果你捕获到异常,那么程序还能从补货点开始执行。如果一直没有被捕获到,那程序就会跟没有异常机制一样崩溃。

但是要用好这个特性很难很难,你要保证try区域的代码用到的所有调用都是异常安全的,才能让程序在异常发生后,还能像没事一样继续运行。

# 尽量保证函数异常安全

这里举一个例子来说明异常安全在代码实现过程中的考虑。

```

class Menu{

public:

    void changeSrc(const string imgName);

private:

    Mutex mutex;

    Image *srcImg;

  int imgCnt;

};

void Menu::changeSrc(const string& imgName) throw()

{

    lock(&mutex);

    delete srcImg;

    imgCnt++;

    srcImg = new Image(imgSrc);

    unlock(&mutex);

```

上面的changeSrc函数实现存在了很多问题,首先他声称throw(), 表明自己不抛异常,实际上delete 和 new 都是有可能抛出异常的。函数末尾的throw() 只是君子约定,不作数,他是否真实的不抛异常,不看这个声明,而是要看他的具体实现。所以throw()几乎没有参考意义。除非你很信任这个函数的开发者,坚信对方说throw()就一定不会抛异常。

在上面这个函数中至少存在2个主要问题,1)如果delete或者new异常,会导致,lock资源泄露。 解决办法是要把lock封装在对象中。2)这个函数的代码顺序是先释放了srcImg 然后再为srcImg New 新的资源。那问题是如果new异常,会导致srcImg变成野指针。这里的解决方法有多种,一是利用copy and swap技术,一种是利用智能指针的reset。

先说下如何利用智能指针。 在类里面不维护Image*类型的数据, 而是维护shared_ptr<Image> 类型的智能指针对象

```

class Menu{

public:

    void changeSrc(const string imgName);

private:

    Mutex mutex;

    shared_ptr<Image> smart_srcImg;

  int imgCnt;

};

void Menu::changeSrc(const string& imgName) throw()

{

    lock_gard<std::mutex> mtxGard(mutex);

    smart_srcImg.reset(new Image(imgName));

    imgCnt++;

}

```

利用智能指针的reset,如果new异常了,那么就的智能指针指向的资源还不会释放。只有new成功了,reset函数才会释放旧的资源。

接下来说明如何利用copy and swap思想手动解决问题代码,见注释

```

void Menu::changeSrc(const string& imgName) throw()

{

    lock_gard<std::mutex> mtxGard(mutex);

    //delete srcImg; 先不要着急修改原有的对象,而应该,把原有对象拷贝生成一份临时对象。Image* tmp = srcImg; tmp =new Image(imgSrc);

//保证临时对象需要修改的东西已经修改完毕,需要的新资源已经new成功后。此后不会发生异常了,然后把旧的对象和这个临时对象swap,然后删除旧对象的关联的资源

swap(srcImg, tmp);

//离开作用域后tmp会自动释放资源,当然这里的例子做不到。因为tmp仅仅只是指针而已。他做不到自动释放关联的资源。这里仅仅示意copy and swap的流程。

    imgCnt++;

```

相关文章

网友评论

      本文标题:Effective c++ 学习笔记(item29)

      本文链接:https://www.haomeiwen.com/subject/bopbortx.html