2017-07-19 60 views
1

一個文件流的析構函數可以拋出異常,例如,如果文件關閉操作失敗?文件流析構函數可以在C++中拋出異常嗎?

auto f = new std::ofstream("data.txt"); 
    f->exceptions(std::ofstream::failbit | std::ofstream::badbit); 
    ... 
    delete f; // May throw?  

我可以通過手動關閉流來防止這種異常嗎?

auto f = new std::ofstream("data.txt"); 
    f->exceptions(std::ofstream::failbit | std::ofstream::badbit); 
    ... 
    f->close(); 
    delete f; // May throw?  
+1

見https://stackoverflow.com/q/748014/72178。 – ks1322

+4

沒有標準類從析構函數中拋出,也不應該拋出它。 – molbdnilo

回答

2

從析構函數中拋出是危險的,應該避免。沒有C++標準庫的對象從析構函數中拋出。 C++語言隱含地假定析構函數聲明爲noexcept

實際上,這是std::basic_filebuf<>::close()std::basic_filebuf<>::~std::basic_filebuf()之間的唯一區別:後者調用close()但捕獲任何異常而不重新拋出。因此,如果您想要解決關閉底層文件的問題,您可以明確地調用ofstream::rdbuf()->close()。然而ofstream::close()有效地呼叫rdbuf()->close()並捕獲任何異常。在這種情況下,它設置failbitIFF您已設置相應的流的異常掩碼(通過ofstream::exceptions(),當你在你的問題做了)拋出std::ios_base::failure類型的(不同的)異常。

因此,概括地說:

  • 如果使用RAII(即析構函數)關閉文件,沒有 異常將被傳播出來的析構函數,即使 底層的文件無法被關閉乾淨。在這種情況下, failbit將被設置。
  • 如果您明確地close()std::ofstream,則根據流的例外掩碼,std::ios_base::failure在遇到關閉文件時可能會出現問題。
+0

@霍爾特謝謝。我編輯了我的答案以反映您的評論。 – Walter

相關問題