Question

Il y a quelques jours, j'ai décidé que ce serait amusant d'écrire une sous-classe de streambuf qui utiliserait mmap et en lecture. Je regardais comment mon STL (SGI) mis en œuvre filebuf et réalisé que basic_filebuf contient un FILE*. Donc, héritant de basic_filebuf est hors de question.

Je hérité de basic_streambuf. Alors je voulais lier mon mmapbuf à un fstream.

Je pensais que la seule chose que je dois faire serait de copier l'interface implicite de filebuf ... mais qui était une erreur évidente. Dans le SGI, basic_fstream est propriétaire d'un basic_filebuf. Peu importe si je l'appelle basic_filestream.std::::ios::rdbuf( streambuf* ), le filestream ignore complètement et utilise son propre filebuf.

Alors maintenant, je suis un peu confus ... Bien sûr, je peux créer mon propre mmfstream, ce serait la copie exacte / coller du fstream mais que

sons vraiment pas à sec orienté.

Ce que je ne comprends pas, est: pourquoi fstream est si étroitement lié à filebuf, de sorte qu'il est impossible d'utiliser quoi que ce soit d'autre qu'un filebuf Le point entier de séparation des flux et bufs est que l'on peut utiliser un jet avec un tampon différent.

Solutions:

=> filestream doit compter sur l'interface implicite de filebuf. Autrement dit, fstream devrait être templated par une classe de streambuf. Cela permettrait à chacun de fournir sa propre sous-classe de streambuf à un fstream tant qu'il implémente l'interface implicite de filebuf. Problème:. Nous ne pouvons pas ajouter un paramètre de modèle à fstream car il casserait sélecteurs de modèle en utilisant fstream comme paramètre de modèle de modèle

=> filebuf doit être une classe virtuelle pure sans attributs supplémentaires. Alors que l'on peut hériter de sans porter tout son fichier * ordures.

Vos idées sur le sujet?

Était-ce utile?

La solution

Consultez mapped_file dans le Boost.Iostreams bibliothèque. Je ne l'ai jamais utilisé utilisé moi-même, mais il semble que cela pourrait déjà faire ce que vous avez besoin.

EDIT: Oops, relisez vos questions et je vois que vous faites cela pour le plaisir. Peut-être que vous pouvez inspirer de Boost.Iostreams?

Autres conseils

dans les flux d'entrées-sorties de la conception, la plupart des courants réels de la fonctionnalité (par opposition à la fonctionnalité de tampons de flux) est mis en oeuvre dans std::basic_istream, std::basic_ostream, et de leurs classes de base. Les classes de flux de chaîne et le fichier sont plus ou moins que des emballages de commodité qui font en sorte un cours d'eau avec le type de tampon est instancié .

Si vous souhaitez étendre les cours d'eau, vous presque toujours envie de donner votre propre classe tampon de flux , et vous avez besoin presque jamais de fournir votre propre classe de flux. .

Une fois que vous avez votre propre type de mémoire tampon de flux, vous pouvez alors faire le tampon pour tout objet de flux que vous arrive d'avoir autour. Ou vous dérivez vos propres classes de std::basic_istream, std::basic_ostream et std::basic_iostream qui instancie votre mémoire tampon de flux et de le transmettre à leurs classes de base.
Ce dernier est plus pratique pour les utilisateurs, mais vous oblige à écrire du code-plaque de la chaudière pour le instanciation de la mémoire tampon (à savoir les constructeurs pour la classe de flux).

Pour répondre à votre question: flux de fichiers et tampon sont accouplées si étroitement que l'ancien existe seulement pour faciliter la création de ce dernier. L'utilisation d'un flux de fichiers, il est facile de mettre tout en place.
En utilisant votre propre classe de flux pour envelopper la construction de votre propre tampon de flux ne devrait pas être un problème, puisque vous ne devriez pas passer autour des flux fichier de toute façon, mais seulement (références) aux classes de base.

fstream est pas en soi une grande classe. Il hérite de basic_stream de fournir un soutien pour toutes les opérations de << et >>, contient une steambuf spécialisée qui doivent être initialisé, et les constructeurs correspondant à transmettre les paramètres au constructeur de streambuf.

Dans un sens, ce que vous avez écrit sur votre solution est basé sur un modèle OK. Mais basic_stream peut également être dérivé en tcp_stream par exemple. Dans ce cas, les constructeurs de fstream sont un peu inutile. Ainsi, vous devez fournir une nouvelle classe de tcpstream, héritant de basic_stream avec les bons paramètres pour les constructeurs pour pouvoir créer le tcp_stream. En fin de compte, vous n'utiliser quoi que ce soit de fstream. La création de ce nouveau tcpstream est une question d'écrire 3 ou 4 fonctions seulement.

En fin de compte, vous dériverait de la classe fstream sans aucune véritable raison. Cela ajouterait plus de couplage dans la hiérarchie des classes, couplage non nécessaire.

Le point entier de std::fstream est qu'il est un _ F std::stream à base _ile. Si vous voulez un std::stream ordinaire soutenu par votre mmstreambuf, vous devez créer un mmstreambuf et le transmettre à std::stream::stream(std::streambuf*)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top