C 建構函式 析構函式與丟擲異常

2022-02-13 05:23:10 字數 1023 閱讀 8208

【問題】

建構函式可以丟擲異常麼?析構函式可以嗎?

【分析】

從語法上來說,建構函式和析構函式都可以丟擲異常。但從邏輯上和風險控制上,建構函式可以,析構函式不推薦丟擲異常。

(1)建構函式可以丟擲異常

無論何時,從建構函式中丟擲異常都是可以的。動態建立物件要進行兩個操作:分配記憶體和呼叫建構函式。若在分配記憶體時出錯,會丟擲bad_alloc異常;若在呼叫建構函式初始化時出錯,會不會存在記憶體洩漏呢?答案是不會。

new運算子保證不會出現記憶體洩漏:

c++ code 

1t *p = new

t;將被編譯器轉換給類似下面的樣子:

c++ code 12

3456

78910

1112

1314

void

allocate_and_construct()

catch

(...)

}(2)析構函式不推薦丟擲異常,如果析構函式可能丟擲異常,那麼必須要求在析構函式內消化所有異常或者結束程式。

more effective c++提出兩點理由(析構函式不能丟擲異常的理由)

1)如果析構函式丟擲異常,則異常點之後的程式不會執行,如果析構函式在異常點之後執行了某些必要的動作比如釋放某些資源,則這些動作不會執行,會造成諸如資源洩漏的問題。 [正常情況下呼叫析構函式丟擲異常導致資源洩露]

2)通常異常發生時,c++的機制會呼叫已經構造物件的析構函式來釋放資源,此時若析構函式本身也丟擲異常,則前乙個異常尚未處理,又有新的異常,會造成程式崩潰的問題。 [在發生異常的情況下呼叫析構函式丟擲異常,會導致程式崩潰]

解決方案:

1) 如果某個操作可能會丟擲異常,class應提供乙個普通函式(而非析構函式),來執行該操作。目的是給客戶乙個處理錯誤的機會。

2) 如果析構函式中異常非拋不可,那就用try catch來將異常吞下,必須要把這種可能發生的異常完全封裝在析構函式內部,決不能讓它丟擲函式之外。

【參考】

C 建構函式 析構函式與丟擲異常麼?

從語法上來說,建構函式和析構函式都可以丟擲異常。但從邏輯上和風險控制上,建構函式可以,析構函式不推薦丟擲異常。無論何時,從建構函式中丟擲異常都是可以的。動態建立物件要進行兩個操作 分配記憶體和呼叫建構函式。若在分配記憶體時出錯,會丟擲bad alloc異常 若在呼叫建構函式初始化時出錯,會不會存在記...

析構函式丟擲異常

看了下effective c 關於析構函式丟擲異常的一些描述。然後自己網上查了下。發現一篇說的不錯的。轉了。具體出處不知道是 1.丟擲異常 1.1 丟擲異常 也稱為拋棄異常 即檢測是否產生異常,在c 中,其採用throw語句來實現,如果檢測到產生異常,則丟擲異常。該語句的格式為 throw 表示式 ...

建構函式和析構函式中丟擲異常

不會造成記憶體洩漏 1 new乙個物件有兩個過程 a.向系統申請記憶體空間 b.在申請的記憶體空間上執行建構函式,初始化物件。2 內部物件構造先於物件本身。3 物件在建構函式丟擲異常後,系統會負責清理構造物件時申請的記憶體,但不會呼叫物件析構函式。也就是說構造物件的記憶體會被釋放掉,已經完成例項化的...