【More Effective C++】異常
阿新 • • 發佈:2022-03-10
條款九:利用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{...}; 2void 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%,速度也會下降該範圍。