Frage

Vor einigen Tagen habe ich beschlossen, dass es Spaß machen würde, a zu schreiben streambuf Unterklasse, die verwenden würden mmap und Read-Ahead. Ich habe mir angesehen, wie mein STL (SGI) implementiert wurde filebuf und erkannte das basic_filebuf enthält ein FILE*. Also Erben von basic_filebuf ist nicht in Frage.

Also habe ich von geerbt basic_streambuf. Dann wollte ich meine binden mmapbuf zu einem Fstream.

Ich dachte, das einzige, was ich tun müsste, wäre, die implizite Schnittstelle von zu kopieren filebuf... aber das war ein klarer Fehler. Im SGI, basic_fstream besitzt a basic_filebuf. Egal, ob ich anrufe basic_filestream.std::::ios::rdbuf( streambuf* ), der fileStream ignoriert es vollständig und verwendet seine eigene filebuf.

Jetzt bin ich ein bisschen verwirrt ... sicher, ich kann meine eigenen erstellen mmfstream, das wäre die genaue Kopie/Einfüge der fstream Aber das klingt wirklich nicht trocken orientiert.

Was ich nicht verstehen kann, ist: warum tut fstream ist so eng mit filebuf, damit es nicht möglich ist, etwas anderes als a zu verwenden filebuf? Der springende Punkt der Trennung von Streams und Bufs ist, dass man einen Stream mit einem anderen Puffer verwenden kann.

Lösungen:

=> filestream sollte sich auf die implizite Schnittstelle von verlassen filebuf. Das heißt, Fstream sollte von einer Streambuf -Klasse vorgeschubt werden. Das würde es jedem ermöglichen, eine eigene Streambuf -Unterklasse für a zu geben fstream Solange es impliziert filebufImplizite Schnittstelle. Problem: Wir können keinen Vorlagenparameter hinzufügen fstream Da würde es die Vorlagenauswahlsportler unter Verwendung des Gebrauchs unterbrechen fstream als Vorlagenvorlageparameter.

=> filebuf sollte eine reine virtuelle Klasse ohne zusätzliche Attribute sein. Damit man sich daraus erben kann, ohne all seine Datei* Müll zu tragen.

Ihre Ideen zu diesem Thema?

War es hilfreich?

Lösung

Kasse Zugeordneter in dem Boost.IOStreams Bibliothek. Ich habe es selbst nie benutzt, aber es scheint, als hätte es bereits das tun, was Sie brauchen.

Bearbeiten: Oops, lesen Sie Ihre Fragen noch einmal und ich sehe, dass Sie dies zum Spaß tun. Vielleicht können Sie sich von Boost.isistreams inspirieren lassen?

Andere Tipps

Im Entwurf der IO -Streams werden die meisten Funktionen der tatsächlichen Streams (im Gegensatz zur Funktionalität der Streampuffer) implementiert in std::basic_istream, std::basic_ostream, und ihre Basisklassen. Die String- und Dateistreamklassen sind mehr oder weniger nur bequeme Wrapper, die sicherstellen, dass ein Stream mit dem richtigen Puffertyp instanziiert ist.

Wenn Sie die Streams erweitern möchten, Sie möchten fast immer Ihre zur Verfügung stellen eigene Stream -Pufferklasse, und Sie müssen fast nie Ihren eigenen Stream -Kurs anbieten. .

Sobald Sie Ihren eigenen Stream -Puffer -Typ haben, können Sie ihn zum Puffer für jedes Stream -Objekt machen, das Sie zufällig haben. Oder Sie leiten Ihre eigenen Klassen ab von std::basic_istream, std::basic_ostream, und std::basic_iostream Was Ihren Stream -Puffer instanziiert und an ihre Basisklassen weiterleitet.
Letzteres ist für Benutzer bequemer, erfordert jedoch, dass Sie einen Kesselplattencode für die Instanziierung des Puffer (nämlich Konstruktoren für die Stream-Klasse) schreiben.

Um Ihre Frage zu beantworten: Dateiströme und Dateipuffer sind so fest gekoppelt, weil erstere nur existiert, um die Erstellung des letzteren zu erleichtern. Wenn Sie einen Dateistrom verwenden, können Sie alles einfach einstellen.
Wenn Sie Ihre eigene Stream -Klasse verwenden, um die Konstruktion Ihres eigenen Stream -Puffers zu wickeln, sollte kein Problem sein, da Sie sowieso keine Dateiströme, sondern nur (Referenzen) an die Basisklassen weitergeben sollten.

fstream An sich ist keine große Klasse. Es erbt von basic_stream Um alle Unterstützung zu unterstützen << und >> Operationen enthält eine spezialisierte steambuf die initialisiert werden müssen, und die entsprechenden Konstruktoren, um die Parameter an die zu übergeben streambuf Konstrukteur.

In gewisser Weise ist das, was Sie über Ihre Vorlagenlösung geschrieben haben, in Ordnung. Aber basic_stream kann auch in a abgeleitet werden tcp_stream zum Beispiel. In diesem Fall die Konstrukteure von fstream sind ein bisschen nutzlos. Daher müssen Sie eine neue bereitstellen tcpstream Klasse, Erben von basic_stream mit den richtigen Parametern, damit die Konstrukteure das erstellen können tcp_stream. Am Ende würden Sie nichts von verwenden fstream. Dieses neue erstellen tcpstream ist nur 3 oder 4 Funktionen zu schreiben.

Am Ende würden Sie von der abgeleitet fstream Klasse ohne wirklichen Grund. Dies würde eine mehr Kopplung in der Klassenhierarchie und der nicht benötigten Kopplung hinzufügen.

Der springende Punkt von std::fstream ist, dass es ein _ istF_ilbasiert std::stream. Wenn Sie ein gewöhnliches wollen std::stream von Ihrem unterstützt mmstreambuf, dann sollten Sie eine erstellen mmstreambuf und weitergeben std::stream::stream(std::streambuf*)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top