2012-10-04 13 views
6

在面試中遇到此問題的前一天。所以只要引導我。如果在C++構造函數中拋出異常時清除已初始化的資源

如何清理初始化的資源,如果在C++中從構造函數中拋出異常?

+0

這是爲什麼近距離投票?這是一個有效的Q.Don't近投票Q的,因爲你不喜歡它或不理解它。只有當它根據SO政策的資格關閉時才關閉投票。 –

回答

1

,自由的資源,當他們被銷燬(又名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_errorbad_alloc),則已經初始化數據成員string1被破壞,從而釋放該資源。對於這個問題,string2也被銷燬,但是如果構造函數拋出,則string2必須仍爲空,所以沒有特別的效果。

string是管理資源的類的一個例子,但還有很多其他的例子。其中最靈活的被稱爲「智能指針」,可以配置爲管理幾乎任何資源,而不僅僅是像string那樣的自分配字符數組。

1

當拋出異常時,堆棧被展開到捕獲點。因此,所有的東西都在它的內部被破壞了。

問題的關鍵在於,將每個敏感資源包裝到一個類中,該類的析構函數負責處理相關資源。

如果資源是一個堆分配的對象,智能指針就是這樣做的(刪除銷燬時指向的對象),如果資源是一個打開的文件,則流在銷燬時關閉它。 其他一切都需要一個自定義包裝。

但請注意,很多「資源」都是由處理程序表示的,它們是無效的*。 這也可以使用智能poitner,通過初始化然後使用分配的資源並指定刪除功能。

這種技術更好地發揮更多的是品味和機會。

1

執行此操作的最佳方法是: 在構造函數中分配任何資源並釋放析構函數中的任何資源。

C++中的模板對此非常有用,因爲我們可以使對象創建爲原子。

+0

你需要拿出例子和更多的解釋,因爲你看到這個問題已經很好地回答了很少。 –