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

时间:2017-07-19 09:05:22

标签: c++ exception destructor throw filestreams

文件流析构函数是否会抛出异常,例如,如果文件关闭操作失败?

   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 个答案:

答案 0 :(得分:2)

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

事实上,这是std::basic_filebuf<>::close()std::basic_filebuf<>::~std::basic_filebuf()之间的唯一区别:后者调用close()但是在没有重新投掷的情况下捕获任何异常。因此,如果要捕获关闭底层文件的问题,可以显式调用ofstream::rdbuf()->close()。但是,ofstream::close()会有效地调用rdbuf()->close()并捕获任何异常。在这种情况下,它设置failbit iff 您已相应地设置了流的异常掩码(通过ofstream::exceptions(),就像您在问题中所做的那样)抛出(异常)异常类型为std::ios_base::failure

因此,总结一下:

  • 如果你使用RAII(即析构函数)来关闭文件,没有 异常将从析构函数中传播出来,即使是 底层文件无法完全关闭。在这种情况下, 将设置failbit。
  • 如果您明确close() std::ofstream,则根据流的异常掩码,在遇到关闭文件的问题时可能会抛出std::ios_base::failure