【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%,速度也会下降该范围。

posted @ 2022-03-10 21:27  axingzheng  阅读(27)  评论(0)    收藏  举报