2010-11-11 16 views
6

Tengo una función que funciona con std::ostream. Necesito admitir el uso de un archivo C manejar (FILE*). ¿Debo crear mi propia subclase de std::ostream que delega a FILE*?WLEpping FILE * con personalizado std :: ostream

+0

Si quiere volverse loco y volver a cambiarlo, siga adelante. Nada sobre envolver cosas con clases, o ARCHIVO * heredado y estandarizado por separado de C lo convierte en una pregunta en C. Como a Stackoverflowers le encanta señalar, C no es un subconjunto de C++. –

+0

Ver [este] (http://ilab.usc.edu/rjpeters/groovx/classrutz_1_1stdiobuf.html) subclase de 'streambuf' que envuelve' FILE * '. –

+0

@Kazark: Impresionante ... Si publica eso como respuesta, lo aceptaría :) – Akusete

Respuesta

6

Como señala Ben Voigt, desea establecer la subclase streambuf. Hay páginas en el sitio web de la Universidad del Sur de California que tienen el documentation, header y source para una implementación GNU de una subclase streambuf (stdiobuf) que envuelve un FILE*. Tiene algunas dependencias en la biblioteca de la que forma parte (GroovX), pero esas deberían ser fáciles de eliminar (comenzaría eliminando todas las referencias al GVX_TRACE).

Curiosamente, también proporciona una subclase minimalista (stdiostream) de std::iostream, a pesar de lo que dijo Ben Voigt. Pero esto no parece ser necesario, ya que el método rdbuf ("leer búfer"/establecer el búfer de secuencia) que utiliza la clase stdiostream para conectar la clase stdiobuf a un objeto de transmisión es de acceso público.

Puede encontrar más información sobre la creación de subclases streambufhere (consulte particularmente en la parte inferior de la página, donde se explican las funciones virtuales). La implementación vinculada anteriormente anula sync, underflow (a la entrada de soporte) y overflow (a la salida de soporte).

Otras notas sobre la aplicación vinculada:

  • El método init utiliza los métodos setg y setp para establecer los punteros para las secuencias de entrada y de salida.
  • La línea const int num = pptr()-pbase(); está calculando el número de caracteres a enjuagar restando el base output pointer del current output pointer ("poner el puntero").
  • La variable inútilmente denominada om es el parámetro de modo.
  • La variable llamada fd es el descriptor del archivo.
6

No, ostream no está destinado a ser derivado. La forma en que la biblioteca iostreams permite la personalización es suministrando un puntero streambuf al crear un ostream. streambuf tiene muchas funciones virtuales para que pueda cambiar su comportamiento.

Debe derivar directamente del streambuf o de la subclase existente filebuf. Probablemente solo necesite proporcionar la función overflow, los valores predeterminados para todos los demás deberían funcionar correctamente.

+0

Wow que en realidad suena a medio limpiar. –

+0

Bueno, iostreams está diseñado para ser extensible. Hace una semana o así, escribí un 'stingbuf' para permitir que los datos escritos en' cout' se mostraran en un cuadro de texto UI cuando no había una ventana de consola adjunta (simplemente anula 'sync'), y también una entrada' streambuf' subclase usando archivos mapeados en memoria y que estaba en el vecindario de 20-30 veces más rápido que 'ifstream' +' getline' + 'istringstream' Yo había sido usado para el procesamiento de archivos de texto. Es realmente sorprendente lo ineficientes que son las implementaciones de streambuf estándar, porque intentan adaptarse a todos los escenarios posibles. –

+1

En realidad, está perfectamente bien derivar de 'ostream', ver por ejemplo' ofstream'. Sin embargo, tales clases derivadas simplemente proporcionan un ctor de conveneniencia que llama 'ostream :: ostream (streambuf *)'. – MSalters

Cuestiones relacionadas