C++中建構函式和解構函式可以丟擲異常嗎?
阿新 • • 發佈:2019-01-29
一.建構函式
1. 建構函式中丟擲異常,會導致解構函式不能被呼叫,但物件本身已申請到的記憶體資源會被系統釋放(已申請到資源的內部成員變數會被系統依次逆序呼叫其解構函式)。
2. 因為解構函式不能被呼叫,所以可能會造成記憶體洩露或系統資源未被釋放。
3. 建構函式中可以丟擲異常,但必須保證在建構函式丟擲異常之前,把系統資源釋放掉,防止記憶體洩露。(如何保證???使用auto_ptr???)
二.解構函式
1. 不要在解構函式中丟擲異常!雖然C++並不禁止解構函式丟擲異常,但這樣會導致程式過早結束或出現不明確的行為。
2. 如果某個操作可能會丟擲異常,類應提供一個普通函式(而非解構函式),來執行該操作。目的是給客戶一個處理錯誤的機會。
3. 如果解構函式中異常非拋不可,那就用try catch來將異常吞下,但這樣方法並不好,我們提倡有錯早些報出來。
最後總結
1. 建構函式中儘量不要丟擲異常,能避免的就避免,如果必須,要考慮不要記憶體洩露!
2. 不要在解構函式中丟擲異常!
1. 建構函式中丟擲異常,會導致解構函式不能被呼叫,但物件本身已申請到的記憶體資源會被系統釋放(已申請到資源的內部成員變數會被系統依次逆序呼叫其解構函式)。
2. 因為解構函式不能被呼叫,所以可能會造成記憶體洩露或系統資源未被釋放。
3. 建構函式中可以丟擲異常,但必須保證在建構函式丟擲異常之前,把系統資源釋放掉,防止記憶體洩露。(如何保證???使用auto_ptr???)
二.解構函式
1. 不要在解構函式中丟擲異常!雖然C++並不禁止解構函式丟擲異常,但這樣會導致程式過早結束或出現不明確的行為。
2. 如果某個操作可能會丟擲異常,類應提供一個普通函式(而非解構函式),來執行該操作。目的是給客戶一個處理錯誤的機會。
3. 如果解構函式中異常非拋不可,那就用try catch來將異常吞下,但這樣方法並不好,我們提倡有錯早些報出來。
#include <iostream> using namespace std; class A { public: A() {cout<<"A()"<<endl;throw 1;} ~A() {cout<<"~A()"<<endl;throw 2;} }; int main(int argc, char* argv[]) { A* pA = NULL; try { pA = new A(); //類A的建構函式中丟擲異常時(物件沒有建立成功),pA的值是空; //物件本身已申請到的記憶體資源會被系統釋放,但不會呼叫解構函式。 A a; //類A的建構函式中丟擲異常時,解構函式不會被呼叫 } catch (...) { cout<<"caught!"<<endl; } return 0; }
最後總結
1. 建構函式中儘量不要丟擲異常,能避免的就避免,如果必須,要考慮不要記憶體洩露!
2. 不要在解構函式中丟擲異常!