¿Debo cerrar manualmente un ifstream?

¿Debo llamar manualmente a close() cuando uso un std::ifstream ?

Por ejemplo, en el código:

 std::string readContentsOfFile(std::string fileName) { std::ifstream file(fileName.c_str()); if (file.good()) { std::stringstream buffer; buffer << file.rdbuf(); file.close(); return buffer.str(); } throw std::runtime_exception("file not found"); } 

¿Debo llamar a file.close() manualmente? ¿No debería ifstream hacer uso de RAII para cerrar archivos?

NO

Esto es para lo que RAII es, deja que el destructor haga su trabajo. No hay daño al cerrarlo manualmente, pero no es la forma C ++, es la progtwigción en C con clases.

Si desea cerrar el archivo antes del final de una función, siempre puede usar un scope nested.

En el estándar (27.8.1.5 Plantilla de clase basic_ifstream), ifstream debe implementarse con un miembro basic_filebuf contiene el manejador de archivo real. Se mantiene como miembro de modo que cuando un objeto ifstream se destruye, también llama al destructor en basic_filebuf . Y a partir del estándar (27.8.1.2), ese destructor cierra el archivo:

virtual ˜basic_filebuf();

Efectos: Destruye un objeto de clase basic_filebuf . Llamadas close() .

¿Necesitas cerrar el archivo?
NO

¿Deberías cerrar el archivo?
Depende

¿Te preocupan las posibles condiciones de error que podrían ocurrir si el archivo no se cierra correctamente? Recuerde que close calls setstate (failbit) si falla. El destructor llamará a close () automáticamente por causa de RAII, pero no le dejará una forma de probar el bit de falla ya que el objeto ya no existe.

Estoy de acuerdo con @Martin. Si escribe en el archivo, los datos aún pueden estar almacenados en un búfer y es posible que no se graben en el archivo hasta que se llame a close() . Sin hacerlo manualmente, no tienes idea de si hubo un error o no. No reportar errores a un usuario es una muy mala práctica.

No, esto se hace automáticamente por el destructor ifstream. La única razón por la que debe llamarlo manualmente es porque la instancia de fstream tiene un gran scope, por ejemplo, si es una variable miembro de una instancia de clase de vida larga.

Puedes permitir que el destructor haga su trabajo. Pero al igual que cualquier objeto de RAII, puede haber ocasiones en las que el cierre manual puede marcar la diferencia. Por ejemplo:

 #include  using std::ofstream; int main() { ofstream ofs("hello.txt"); ofs << "Hello world\n"; return 0; } 

escribe el contenido del archivo. Pero:

 #include  #include  using std::ofstream; int main() { ofstream ofs("hello.txt"); ofs << "Hello world\n"; exit(0); } 

no. Estos son casos excepcionales en que un proceso se cierra de repente. Un proceso de locking podría hacer algo similar.