【More Effective C++】异常
条款九:利用deconstructor避免资源泄露
将资源封装在对象中(如指针),利用对象离开作用域会自动析构的原理将资源释放,阻止资源的泄露。
条款十:在constructor组织资源泄露
C++只会析构已经构造完成的对象,如果构造过程中出现exceptions,则不会调用析构函数可能出现资源的泄露。
条款十一:禁止exceptions流出deconstructors之外
条款十二:exceptions抛出和传递一个参数、调用一个虚函数之间的差异
- 一个exception的抛出总会发生复制
1 throw classA; //会对classA做复制行为,然后将副本抛出
- 抛出复制行为是由copy constructor执行的,复制以静态对象为本
class B: public classA{...}; void func(){ classB cb; classA & ca = cb; throw ca; //抛出的异常类型为ca }
- by reference捕捉一个exception需要构造一个副本,而by value则为两个(异常传递中允许将临时对象传递给non-const reference)
catch(classA ca); //by value catch(classA & ca);//by reference catch(const classA & ca);//by reference
- 异常传递中只允许两类转换:1、继承体系。2、有形指针转为无形指针。其余类似于int-double类型的转换都不可以。
1 catch(int d){...}; //只能捕捉int类型,double不可以 2 catch(classA & ca){...}; //能捕捉classB 3 catch(const void *){...};//能捕捉所有类型异常
- 虚函数采用最佳吻合的策略,exception采用最先吻合(即要求捕捉子类的语句应该在捕捉父类的语句之前)
条款十三:以by reference的形式捕捉exceptions
以by reference的形式捕捉exception一方面可以减少复制次数,另一方面避免切割问题
1 class B: public classA{...}; 2 void func(){ 3 classB cb; 4 throw cb; //抛出的异常类型为cb 5 } 6 7 //执行的是classA虚函数what() 8 void func2(){ 9 try{ 10 func(); 11 } 12 catch(classA ca){ 13 ca.what(); 14 } 15 } 16 17 //执行的是classB虚函数what() 18 void func3(){ 19 try{ 20 func(); 21 } 22 catch(classA & ca){ 23 ca.what(); // 24 } 25 }
条款十四:exception specifications
C++提供规范,该规范声明一个函数可以抛出的异常类型和个数
1 void f1();//可以抛出任何异常 2 void f2() throw(int, double); //只能抛出int和double类型 3 void f2(){ //允许 4 ... 5 f1(); 6 ... 7 }
条款十五:exception的成本
使用异常使得代码膨胀5%~10%,速度也会下降该范围。
浙公网安备 33010602011771号