經驗1:
析構函數絕對不要吐出異常。如果一個被析構函數調用的函數可能拋出異常,析構函數應該捕捉任何異常,然後吞下它們(不傳播)或結束程序。
示例:
class DBConnection{
public:
static DBConnection create(); //返回DBConnection對象
void close();
};
class DBConn{ //這個class用來管理DBConnection對象
public:
~DBConn(){ //確保數據庫連接總是會被關閉
try{ db.close();}
catch(Exception e){
//制作運轉記錄,記下對close的調用失敗
//1.調用abort結束程序,阻止異常從析構函數傳播出去,
//那樣會導致不明確的行為
std::abort();
//2.或者可以選擇不調用std::abort()函數,直接吞下異常
}
}
private:
DBConnection db;
};
經驗2:
如果客戶需要對某個操作函數運行期間拋出的異常做出反應,那麼class應該提供一個普通函數(而非在析構函數中)執行該操作。
示例:
class DBConnection{
public:
static DBConnection create(); //返回DBConnection對象
void close();
};
class DBConn{ //這個class用來管理DBConnection對象
public:
void close() //雙重保險。客戶可以自己選擇如何處理錯誤
{
db.close();
closed = true;
}
~DBConn(){ //確保數據庫連接總是會被關閉
try{ db.close();}
catch(Exception e){
//制作運轉記錄,記下對close的調用失敗
//1.調用abort結束程序,阻止異常從析構函數傳播出去,
//那樣會導致不明確的行為
std::abort();
//2.或者可以選擇不調用std::abort()函數,直接吞下異常
}
}
private:
DBConnection db;
bool closed;
};