回答
訣竅是使用RAII(資源獲取是初始化)來管理資源。
如果您有指針成員,則使用智能指針而不是原始指針,一旦從構造函數中拋出異常,它將自動執行清理作業。
良好閱讀:
Herb Sutter's excellent GotW article "Construction Failures"
+1鏈接 – Dialecticus
,自由的資源,當他們被銷燬(又名RAII)使用的數據成員。
例如:
struct TwoStrings {
std::string string1;
std::string string2;
TwoStrings(const std::string &input) : string1(input) {
if (!input[1] == ':') {
throw std::logic_error('not a Windows absolute path');
// yes, absolute paths can begin \\, this is a toy example
}
if (input.back() == '\\') {
string2 = input;
} else {
string2 = input + "\\";
}
}
};
如果構造拋出(或者logic_error
或bad_alloc
),則已經初始化數據成員string1
被破壞,從而釋放該資源。對於這個問題,string2
也被銷燬,但是如果構造函數拋出,則string2
必須仍爲空,所以沒有特別的效果。
string
是管理資源的類的一個例子,但還有很多其他的例子。其中最靈活的被稱爲「智能指針」,可以配置爲管理幾乎任何資源,而不僅僅是像string
那樣的自分配字符數組。
當拋出異常時,堆棧被展開到捕獲點。因此,所有的東西都在它的內部被破壞了。
問題的關鍵在於,將每個敏感資源包裝到一個類中,該類的析構函數負責處理相關資源。
如果資源是一個堆分配的對象,智能指針就是這樣做的(刪除銷燬時指向的對象),如果資源是一個打開的文件,則流在銷燬時關閉它。 其他一切都需要一個自定義包裝。
但請注意,很多「資源」都是由處理程序表示的,它們是無效的*。 這也可以使用智能poitner,通過初始化然後使用分配的資源並指定刪除功能。
這種技術更好地發揮更多的是品味和機會。
執行此操作的最佳方法是: 在構造函數中分配任何資源並釋放析構函數中的任何資源。
C++中的模板對此非常有用,因爲我們可以使對象創建爲原子。
你需要拿出例子和更多的解釋,因爲你看到這個問題已經很好地回答了很少。 –
- 1. 異常可拋出的構造函數和初始化。最佳做法
- 2. 用異常拋出構造函數初始化對象的正確方法
- 3. 從構造函數中拋出異常
- 4. ServerSocket的構造函數拋出異常
- 5. JNDI在服務器初始化函數中拋出Servlet異常
- 6. 在C++類的構造函數中拋出異常
- 7. 從構造函數中拋出異常在C++中
- 8. 構造函數和拋出異常
- 9. EJB3構造函數拋出異常?
- 10. Angular2,構造函數DI拋出異常
- 11. 如果分配的內存構造函數拋出異常
- 12. 構造函數中私人成員初始化的差異(C++)
- 13. 初始化構造函數C++
- 14. C++模板構造函數初始化
- 15. c#構造函數與初始化
- 16. 在構造函數中初始化
- 17. 在構造函數中初始化ArrayList
- 18. 初始化在定義與初始化在構造函數中
- 19. C++:處理資源,如果構造函數可能會拋出異常(參考FAQ 17.4]
- 20. 初始化'System.Windows.Controls.Button'拋出一個異常
- 21. 在C++中的類構造函數中初始化列表初始化
- 22. C++中初始化構造
- 23. 如何在C++中初始化嵌套類的構造函數
- 24. C++在構造函數中初始化函數指針
- 25. 構造函數中的初始化塊
- 26. 構造函數在applet中的存在會拋出異常
- 27. 在C中的C++構造函數初始化列表替代?
- 28. C++的構造函數:垃圾而常引用初始化
- 29. 在構造函數中初始化類常量在PHP中
- 30. 運行析構函數,當構造函數拋出異常
這是爲什麼近距離投票?這是一個有效的Q.Don't近投票Q的,因爲你不喜歡它或不理解它。只有當它根據SO政策的資格關閉時才關閉投票。 –