В типичном примере RAII для файлового ввода-вывода в Википедии любые ошибки, возникающие при закрытии файла, проглатываются:
#include <iostream>
#include <string>
#include <fstream>
#include <stdexcept>
void write_to_file (const std::string & message) {
// try to open file
std::ofstream file("example.txt");
if (!file.is_open())
throw std::runtime_error("unable to open file");
// write message to file
file << message << std::endl;
// file will be closed when leaving scope (regardless of exception)
}
Кажется, нет способа определить, произошла ли ошибка при автоматическом закрытии file
; очевидно, можно вызывать только file.rdstate()
, пока file
находится в области видимости.
Я мог бы вызвать file.close()
вручную, а затем проверить наличие ошибки, но мне пришлось бы делать это в каждом месте, где я возвращаюсь из области видимости, что противоречит цели RAII.
Некоторые отмечают, что в деструкторе могут возникать только неустранимые ошибки, такие как повреждение файловой системы, но я не верю, что это правда, потому что AFAIK деструктор очищает файл перед его закрытием, и во время очистки могут возникать исправимые ошибки.
Итак, существует ли общий способ RAII для получения ошибок, возникающих во время уничтожения? Я читал, что создание исключений из деструкторов опасно, так что это не похоже на правильный подход.
Самый простой способ, который я могу придумать, — это зарегистрировать функцию обратного вызова, которую деструктор будет вызывать, если во время уничтожения возникнут какие-либо ошибки. Удивительно, но не похоже, что для этого существует событие, поддерживаемое ios_base::register_callback
. Это похоже на серьезную оплошность, если я что-то не так понял.
Но, возможно, обратный вызов — самый распространенный способ получать уведомления об ошибках во время уничтожения в современных проектах классов?
Я предполагаю, что вызов произвольной функции в деструкторе также опасен, но, возможно, оборачивать вызов в блок try/catch
совершенно безопасно.
std::ofstream
закрывает свой файл при уничтожении, и я спрашиваю, как бы я обработал ошибку закрытия файла, если бы сам разработал аналогичный класс. - person Andy   schedule 20.02.2018file
, гарантированно будут очищены к моменту вызова его деструктора? Потому что, если нет, я предполагаю, что деструктор также очищает вывод перед закрытием файла, во время которого может возникнуть исправимая ошибка. - person Andy   schedule 20.02.2018ofstream
, спасибо! - person Andy   schedule 20.02.2018std::basic_filebuf<...>
, деструктор вызываетclose
, который действительно очищает буфер. - person Some programmer dude   schedule 20.02.2018