Domanda

Alcuni giorni fa, ho deciso che sarebbe stato divertente scrivere una sottoclasse streambuf che avrebbe utilizzato mmap e read-ahead. Ho guardato come il mio STL (SGI) implementato filebuf e si rese conto che basic_filebuf contiene un FILE*. Quindi, che eredita da basic_filebuf è fuori questione.

Così ho ereditato da basic_streambuf. Poi ho voluto legare il mio mmapbuf ad un fstream.

ho pensato che l'unica cosa che avrei dovuto fare sarebbe quella di copiare l'interfaccia implicita di filebuf ... ma questo è stato un chiaro errore. Nella SGI, basic_fstream possiede una basic_filebuf. Non importa se chiamo basic_filestream.std::::ios::rdbuf( streambuf* ), il filestream ignora completamente e utilizza il proprio filebuf.

Così ora sono un po 'confuso ... certo, posso creare il mio mmfstream, che sarebbe la copia esatta / incolla del fstream ma che suoni davvero non Dry-oriented.

Quello che non riesco a capire, è:? Perché fstream è così strettamente accoppiato con filebuf, in modo che non è possibile utilizzare qualsiasi altra cosa che un filebuf Il punto centrale di flussi di separazione e bufs è che si può usare un ruscello con un tampone diverso.

Soluzioni:

=> filestream dovrebbe fare affidamento sull'interfaccia implicita di filebuf. Cioè, fstream dovrebbe essere templato da una classe streambuf. Ciò consentirebbe a tutti di fornire la propria sottoclasse streambuf ad un fstream fintanto che implementa l'interfaccia implicita di filebuf. Problema:. Non siamo in grado di aggiungere un parametro modello per fstream in quanto si spezzerebbe selettori template durante l'utilizzo fstream come parametro di template

=> filebuf dovrebbe essere una classe virtuale pura senza attributi aggiuntivi. In modo che si può ereditare da esso senza portare tutta la sua FILE * spazzatura.

Le vostre idee in proposito?

È stato utile?

Soluzione

mapped_file nel Boost.Iostreams biblioteca. Non ho mai usato usato io stesso, ma sembra che potrebbe già fare ciò che è necessario.

EDIT: Ops, rileggere le vostre domande e vedo che stai facendo questo per divertimento. Forse si può trarre ispirazione da Boost.Iostreams?

Altri suggerimenti

Negli flussi IO progettazione, maggior parte dei flussi reali funzionalità (al contrario di funzionalità al torrente buffers') è implementato in std::basic_istream, std::basic_ostream, e loro classi base. Le classi di stringa e file di flusso sono più o meno semplicemente involucri di convenienza che si assicurano un flusso con il giusto tipo di tampone viene istanziato .

Se si desidera estendere i flussi, si vuole quasi sempre di fornire il tuo propria classe di buffer flusso , e quasi mai bisogno di fornire la propria classe flusso. .

Una volta che avete il vostro tipo di buffer flusso, quindi è possibile rendere il buffer per qualsiasi oggetto stream vi capita di avere intorno. O si deriva le proprie classi da std::basic_istream, std::basic_ostream, e std::basic_iostream che un'istanza il buffer stream e passarlo a loro classi base.
Il secondo è più conveniente per gli utenti, ma richiede di scrivere del codice caldaia-piastra per esemplificazione del tampone (cioè costruttori per la classe di flusso).

Per rispondere alla tua domanda: flussi di file e file di buffer sono accoppiati in modo strettamente perché il primo esiste solo per facilitare la creazione di quest'ultimo. Utilizzando un flusso di file rende facile impostare il tutto.
Utilizzare la propria classe flusso per avvolgere la costruzione del proprio buffer di flusso non dovrebbe essere un problema, dal momento che non si dovrebbe essere passando intorno file di flusso in ogni caso, ma solo (riferimenti) alle classi di base.

fstream di per sé non è una grande classe. Eredita da basic_stream per fornire supporto per tutte le operazioni << e >>, contiene un steambuf specializzato che deve essere inizializzato, e costruttori corrispondenti per passare i parametri al costruttore streambuf.

In un certo senso, quello che hai scritto sulla tua soluzione su modelli è OK. Ma basic_stream può anche essere ricavato in un tcp_stream per esempio. In tal caso, i costruttori di fstream sono un po 'inutile. Quindi è necessario fornire una nuova classe tcpstream, eredita da basic_stream con i parametri corretti per i costruttori siano in grado di creare il tcp_stream. Alla fine, non sarebbe usare qualsiasi cosa, da fstream. La creazione di questo nuovo tcpstream è una questione di scrivere solo 3 o 4 funzioni.

Alla fine, si dovrebbe derivare dalla classe fstream senza alcun motivo reale per. Ciò aggiungere più l'accoppiamento nella gerarchia delle classi, l'accoppiamento non necessari.

Il punto di std::fstream è che si tratta di un _ F std::stream basato _ile. Se si desidera un std::stream ordinaria sostenuta dal vostro mmstreambuf, allora si dovrebbe creare una mmstreambuf e passarlo a std::stream::stream(std::streambuf*)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top