2010-11-11 14 views
6

Ho una funzione che funziona con uno std::ostream. Ho bisogno di sostenere con un handle di file C (FILE*). Devo creare la mia sottoclasse di std::ostream che delega a un numero FILE*?Wrapping FILE * con std personalizzato :: ostream

+0

Se vuoi diventare pazzo e cambiarlo, vai avanti. Niente sul wrapping delle cose con le classi, o FILE * ereditato e standardizzato separatamente da C lo rende una domanda di tipo C. Come Stackoverflow-it ama sottolineare, C non è un sottoinsieme di C++. –

+0

Vedere [this] (http://ilab.usc.edu/rjpeters/groovx/classrutz_1_1stdiobuf.html) sottoclasse di 'streambuf' che include' FILE * '. –

+0

@Kazark: Impressionante ... Se lo pubblichi come risposta, lo accetterei :) – Akusete

risposta

6

Come sottolinea Ben Voigt, si desidera creare una sottoclasse di streambuf. Ci sono pagine sul sito web dell'Università di Southern California che hanno la documentation, header e source per un'implementazione GNU di un streambuf sottoclasse (stdiobuf) che avvolge un FILE*. Ha alcune dipendenze sulla libreria si tratta di una parte di (GroovX), ma quelli dovrebbe essere facilmente rimuovere (vorrei cominciare eliminando tutti i riferimenti a GVX_TRACE).

È interessante notare che fornisce anche una sottoclasse minimalista (stdiostream) di std::iostream, nonostante quanto affermato da Ben Voigt. Ma questo non sembra essere necessario, poiché il metodo ("buffer di lettura"/imposta il buffer del flusso) che la classe stdiostream utilizza per collegare la classe stdiobuf a un oggetto flusso è pubblicamente accessibile.

È possibile trovare ulteriori informazioni sulla sottoclasse streambufhere (guardare in particolare nella parte inferiore della pagina, che illustra le funzioni virtuali). L'implementazione collegata sopra sostituisce sync, underflow (per supportare l'input) e overflow (per supportare l'output).

Ulteriori avvertenze circa l'attuazione collegato:

  • Procedimento init utilizza il setg e setp metodi per impostare i puntatori per le sequenze di ingresso e di uscita.
  • La riga const int num = pptr()-pbase(); sta calcolando il numero di caratteri da svuotare sottraendo base output pointer da current output pointer ("puntatore put").
  • La variabile inutilmente chiamato om è il parametro modalità.
  • la variabile denominata fd è il descrittore di file.
6

No, ostream non deve essere derivato da. Il modo in cui la libreria iostreams permette personalizzazione è fornendo un puntatore streambuf quando si crea un ostream. streambuf ha un sacco di funzioni virtuali in modo da poter cambiare il suo comportamento.

È necessario derivare direttamente da streambuf o dalla sottoclasse esistente filebuf. Probabilmente hai solo bisogno di fornire la funzione overflow, i valori di default per tutti gli altri dovrebbero funzionare bene.

+0

Wow, in realtà suona a metà pulito. –

+0

Bene, iostreams è progettato per essere estensibile. Circa una settimana fa, ho scritto uno 'stingbuf' per permettere che i dati scritti su' cout' comparissero in una casella di testo dell'interfaccia utente quando non vi era alcuna finestra della console collegata (semplicemente sincronizzare 'sync'), e anche una sottoclasse' streambuf' di input usando file mappati in memoria e che era in un raggio di 20-30 volte più veloce di 'ifstream' +' getline' + 'istringstream' ero stato usato per l'elaborazione del file di testo. È davvero sorprendente quanto siano inefficienti le implementazioni standard di streambuf, perché cercano di adattarsi a ogni possibile scenario. –

+1

In realtà, è perfettamente corretto derivare da 'ostream', si veda ad esempio' ofstream'. Tuttavia, tali classi derivate forniscono solo un convenzionence ctor che chiama 'ostream :: ostream (streambuf *)'. – MSalters

Problemi correlati