文件流析构函数可以在 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
。
文件流析构函数是否可以抛出异常,例如,如果文件关闭操作失败?
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
。