2016-05-31 3 views
2

В языке C++ существует несколько способов открытия и работы с файлом. Однако RAII-подход очень популярен, так как destruktor заботится о освобождении памяти.RAII с файловым потоком

Но как насчет закрытия фильтра? Насколько я знаю, деструктор должен закрыть файл в любом случае. Однако деструктору также не разрешено исключать какие-либо исключения. Поэтому, если я не закрываю свой поток, и он разрушается в конце блока, я могу потерять информацию об ошибке, которая может возникнуть при закрытии.

Я считаю, что это правильно? Несмотря на подход RAII, я должен всегда закрывать свои потоки?

Пример:

{ 
    std::ofstream ofs; 
    ofs.open ("test.txt"); 

    ofs << "blablabla"; 

    //do i need the following? 
    ofs.close(); 
} 
+0

Объект файлового потока должен быть разрушен (и, следовательно, закрыт, без исключений), когда объект, в котором он содержится, разрушен. Не нужно явно закрывать файл в деструкторе. –

+0

Нет, вам не нужно вручную '.close()', это _whole point_ of RAII. – emlai

ответ

3

Ответ зависит от того, хотите ли вы реагировать на ошибку при закрытии или нет.

Если вы хотите реагировать, вы должны close вручную и проверить на наличие ошибок (не в состоянии закрыть установит failbit):

std::ofstream str; 
// Do something 
str.close(); 
if (str.fail()) { 
    // react on error 
} 

Если вы не хотите, чтобы реагировать, зачем? Просто позвольте деструктору закрыть файл

3

Вы должны позволить fstream деструктор закрыть файл.

Как вы сказали, деструктор не будет бросать, поэтому вы не увидите никаких ошибок, возникающих при закрытии файла, но функция-член std::basic_fstream::close() имеет возвращаемый тип void, так что не может сигнализировать об ошибке , Не беспокойтесь об этом; просто позвольте деструктору закрыть файл как для любого другого класса RAII.


Отметим, что buffer, что лежит в основе fstream имеет функцию в close() член тоже. Эта функция возвращает NULL, если произошла ошибка, или указатель this на успех. Эта функция вызывается из деструктора basic_filebuf, который, в свою очередь, вызывается из деструктора basic_fstream. Вы не должны называть это прямо при нормальном использовании.

Смежные вопросы