¿Cómo creo mi propio ostream / streambuf?

Para fines educativos, quiero crear un ostream y un buffer de transmisión para hacer:

  1. corregir endians al hacer << myVar;
  2. almacenar en un contenedor deque en lugar de usar std: cout o escribir en un archivo
  3. registre datos adicionales, como cuántas veces hice <<, cuántas veces escribí, la cantidad de bytes que escribí y cuántas veces descargué (). Pero no necesito toda la información.

Intenté sobrecargarlo pero fallé horriblemente. Intenté sobrecargar escribir escribiendo

ostream& write( const char* s, streamsize n ) 

en mi clase basic_stringstream2 (copié paste basic_stringstream en mi archivo cpp y lo modifiqué) pero el código seguía usando basic_ostream. Miré a través del código y parece que tengo que sobrecargar xsputn (que no se menciona en esta página http://www.cplusplus.com/reference/iostream/ostream ), pero ¿qué más debo sobrecargar? y cómo construyo mi clase (¿qué necesita para heredar, etc.)?

    El enfoque canónico consiste en definir tu propio streambuf. Deberías echar un vistazo a:

    • Artículos de Angelika LAnger sobre la derivación IOStreams
    • Artículos de James Kanze sobre filtrado de streambufs
    • boost.iostream para ejemplos de aplicación

    Para A + C) Creo que deberías mirar facetas, ellas modifican cómo los objetos se escriben como personajes. También puede almacenar estadísticas aquí sobre cuántas veces transmitió sus objetos. ¿Cómo puedo formatear mis propios objetos cuando uso flujos STL? para un ejemplo.

    Para B) Necesita crear su propio streambuf y conectar su ostream a ese búfer (argumento constructor). Ver los enlaces de Luc + Derivar nuevas clases de streambuf . En resumen, debe implementar esto para un ostream (mínimo):

    • desbordamiento (poner un único búfer o un búfer de descarga) ( enlace )
    • xsputn (poner una matriz char en el búfer) ( enlace )
    • sincronización ( enlace )

    No estoy seguro de que lo que quieras hacer sea posible. Los < < operadores no son virtuales. Por lo tanto, podría definir su yourstream &operator < < (yourstream &strm, int i) para hacer lo que desee con la conversión y conteo de endian, y funcionará cuando su código lo llame directamente. Pero si transfiere un objeto de flujo de datos a una función que espera un ostream, cada vez que esa función llame a < < , irá a la versión original de ostream en lugar de a la suya.

    Según tengo entendido, las instalaciones de flujos se han configurado para que pueda definir "fácilmente" un nuevo tipo de flujo que utiliza un tipo diferente de búfer (como, por ejemplo, una deque de caracteres), y puede agregar fácilmente soporte para sacando tus propias clases a través de < < . No creo que tengas la intención de redefinir la capa intermedia entre ellos.

    Y, en particular, el punto entero de la interfaz < < es proporcionar una salida de texto con un buen formato, mientras que parece que realmente quieres una salida binaria. (De lo contrario, la referencia a "endian" no tiene sentido.) Incluso suponiendo que hay alguna forma de hacerlo, no sé, producirá resultados binarios incómodos en el mejor de los casos. Por ejemplo, considere la sobrecarga del usuario final para generar un punto en el espacio 3D. La versión de usuario final de < < probablemente hará algo como < < '(' << x << ", " << y << ", " << z << ')' . Eso se verá bien en una secuencia de texto, pero hay muchos caracteres desperdiciados y completamente inútiles en una secuencia binaria, que idealmente usaría < < x << y << z . (¿Y cuántas llamadas a < < deben tener en cuenta?)