Почему в потоках стандартной библиотеки С++ используется семантика open()
/close()
, отделяемая от времени жизни объекта? Закрытие при уничтожении может по-прежнему технически создавать классы RAII, но независимость приобретения/освобождения оставляет дыры в областях, где дескрипторы могут указывать на ничего, но все же требуют проверки времени выполнения, чтобы поймать.
Почему дизайнеры библиотеки выбрали свой подход по поводу открытия только в конструкторах, которые бросают неудачу?
void foo() {
std::ofstream ofs;
ofs << "Can't do this!\n"; // XXX
ofs.open("foo.txt");
// Safe access requires explicit checking after open().
if (ofs) {
// Other calls still need checks but must be shielded by an initial one.
}
ofs.close();
ofs << "Whoops!\n"; // XXX
}
// This approach would seem better IMO:
void bar() {
std_raii::ofstream ofs("foo.txt"); // throw on failure and catch wherever
// do whatever, then close ofs on destruction ...
}
Лучшая формулировка вопроса может заключаться в том, что доступ к незакрытому fstream
когда-либо стоит иметь. Контроль продолжительности открытого файла с использованием продолжительности работы с рукояткой, по-видимому, не является бременем, но на самом деле является преимуществом безопасности.