Может ли деструктор файлового потока вызвать исключение в 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

Решение

Бросок от деструктора опасен и его следует избегать. Ни один объект стандартной библиотеки 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 (т.е. деструктор), чтобы закрыть файл, нет
    исключения будут распространяться из деструктора, даже если
    базовый файл не может быть закрыт чисто. В этом случае
    failbit будет установлен.
  • если вы явно close() std::ofstreamзатем, в зависимости от маски исключения потока, std::ios_base::failure может быть брошено при возникновении проблемы с закрытием файла.
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]