More Effective C++总结(3):异常

本文探讨了C++中如何通过正确使用智能指针、构造函数及析构函数来避免资源泄漏,同时提供了如何安全地处理异常以确保程序稳定性的策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

条款9: 使用析构函数防止资源泄漏

下面代码会产生的问题:pa->processAdoption()可能抛出异常,导致delete不被执行

void processAdoption(istream& datasource)
{
    while(datasource)
    {
        ALA* pa = readALA(datasource);
        pa->processAdopation();
        delete pa;
    }
}

解决方案:

使用智能指针,保证析构函数会被执行.


条款10: 防止构造函数里的资源泄漏

1) C++只销毁构造完全的函数,构造完全的对象指它的构造函数被完全执行.如果构造函数抛出异常,析构函数不可能被执行到.

2) 应该把声明为指针的类成员替换成他们相应的auto_ptr对象,在抛出异常的时候构造函数可以避免资源泄漏.


条款11: 阻止异常传递到析构函数以外

1) 析构函数抛出异常会导致之后的代码无法执行,造成资源泄漏.

2) 析构函数抛出异常时可能是另外一个异常调用,导致terminate.


条款12: 理解抛出异常与传递参数或者调用虚函数之间的不同

区别:

1) 函数调用的时候,控制权最终返回给调用者.当抛出异常的时候,控制权不回返回给抛出者.异常对象总是要被拷贝,当以传值方式被捕获得时候,他们被拷贝两次.

2) 函数调用者和被调函数之间,异常抛出者和捕获者之间都存在类型匹配,而他们所遵循的类型匹配是不同的.

3) catch语句永远以他们所出现的顺序被执行.最先匹配.


1. C++要求对象必须以拷贝的形式抛出异常,即使被抛出的对象没有被销毁的危险,他还是要以拷贝的形式被抛出.

2. 当一个对象作为异常被拷贝的时候,这个拷贝是由该对象的拷贝构造函数来实施,这个拷贝构造函数是指对象的静态类型而不是动态类型所对应的那个构造函数.拷贝永远是基于对象的静态类型.

catch (Widget& w)
{
    ...
    throw;
}

catch (Widget& w)
{
    ...
    throw w;
}

应该使用第一个,因为第二个类型总是Widget,因为w的静态类型是widget

第二个还会有效率问题

3. 两次拷贝问题

任何异常发生是都会产生临时拷贝.

catch (Widget w)                // 2次拷贝
catch (Widget& w)               // 1次拷贝
catch (const Widget& w)         // 1次拷贝

条款13: 通过引用捕获异常

1) 通过值捕获异常的问题: 2次拷贝  可能会产生切割

2) 通过指针捕获异常的问题:  不知道时候需要delete    可能返回的是局部对象地址

3) 应该通过引用捕获异常






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值