Effective C++讀書筆記之八:別讓異常逃離析構函數

Item 08: Prevent exceptions from leaving destructors

對C++而言,在兩個異常同時存在的情況下,程序若不是結束執行就是導致不明確行爲。這就意味着,當你使用容器或是數組來存放classes時,如果其中2個classes的析構函數拋出異常,那將會導致不明確行爲。而容器和數組並非遇上麻煩的必要條件,C++不喜歡析構函數吐出異常。

假設你要使用一個class負責數據庫連接:

class DBConnection
{
public:
	...
	static DBConnection creat();//這個函數返回DBConnection對象;
	
	void close();//關閉聯機;失敗則拋出異常 
}

爲確保客戶不忘記在DBConnection對象身上調用close(),一個合理的想法是創建一個用來管理DBConnection資源的class,並在其析構函數中調用close。

class DBCorn
{
public:
	...
	void close()   //供客戶使用的新函數 
	{
		db.close();
		closed=true;
	} 
	~DBCorn()
	{
		if(!closed)
		{
			db.close();//關閉連接(如果客戶不這麼做的話) 
		}
		catch(...)
		{
			...        
			製作運轉記錄,記下對close的調用失敗   //如果關閉動作失敗
			                                      //記錄下來並結束程序或吞下異常         
		}
	}
private:
	DBConnection db;
	bool closed;
};

如果某個操作可能在失敗時拋出異常,而又存在某種必須處理該異常,那麼該異常必須來自析構函數以外的某個函數。因爲析構函數吐出異常就是危險,總會帶來“過早結束程序”或“發生不明確行爲”的風險。

請記住:
1.析構函數絕對不要吐出異常。如果一個被析構函數調用的函數可能拋出異常,析構函數應該捕捉任何異常,然後吞下它們(不傳播)或結束程序。
2.如果客戶需要對某個操作函數運行期間拋出的異常做出反應,那麼class應該提供一個普通函數(而非在析構函數中)執行該操作。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章