1. 程式人生 > 其它 >【More Effective C++】異常

【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%,速度也會下降該範圍。