文件流析构函数可以在 C++ 中抛出异常吗?

Can a file stream destructor throw an exception in 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?     

从析构函数中抛出是危险的,应该避免。 C++ 标准库的任何对象都不会从其析构函数中抛出。 C++ 语言隐式假定析构函数声明为 noexcept.

其实这是std::basic_filebuf<>::close() and std::basic_filebuf<>::~std::basic_filebuf(): the latter calls close() but catches any exception without re-throwing. So, if you want to catch problems with closing the underlying file, you could explicitly call ofstream::rdbuf()->close(). However ofstream::close() effectively calls rdbuf()->close() and catches any exceptions. In this case, it sets the failbit and iff you have set the stream's exception mask accordingly (via ofstream::exceptions(), as you did in your question) throws a (different) exception of type std::ios_base::failure的唯一区别。

因此,总结一下:

  • 如果你使用RAII(即析构函数)关闭文件,不 异常将从析构函数中传播出去,即使 基础文件无法干净地关闭。在这种情况下, 将设置故障位。
  • 如果您显式 close() std::ofstream,则根据流的异常掩码,在遇到文件关闭问题时可能会抛出 std::ios_base::failure