文件流析构函数是否可以在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()std::basic_filebuf<>::~std::basic_filebuf()之间的唯一区别:后者调用close()但捕获任何异常而不重新抛出。因此,如果要捕获关闭基础文件时出现的问题,可以显式调用ofstream::rdbuf()->close()。但是,ofstream::close()有效地调用rdbuf()->close()并捕获任何异常。在这种情况下,它会设置failbit并且如果您相应地设置了流的异常掩码(通过ofstream::exceptions(),就像您在问题中所做的那样(抛出类型std::ios_base::failure的(不同的(异常。

因此,总结一下:

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

最新更新