対応するストリームを書き直さずにStreamBufから派生します
質問
数日前、私は書くのが楽しいと決めました streambuf
使用するサブクラス mmap
そして読み続けています。 STL(SGI)がどのように実装されたかを見ました filebuf
そしてそれを実現しました basic_filebuf
含む FILE*
. 。だから継承 basic_filebuf
問題外です。
だから私は継承した basic_streambuf
. 。それから私は私をバインドしたかった mmapbuf
fstreamへ。
私がしなければならない唯一のことは、の暗黙のインターフェースをコピーすることだと思いました filebuf
...しかし、それは明らかな間違いでした。 SGIで、 basic_fstream
所有 basic_filebuf
. 。電話しても basic_filestream.std::::ios::rdbuf( streambuf* )
, 、Filestreamはそれを完全に無視し、それ自身を使用します filebuf
.
だから今、私は少し混乱しています...確かに、私は自分のものを作成することができます mmfstream
, 、それは正確なコピー/ペーストです fstream
しかし、それは本当に乾燥志向ではないように聞こえます。
私が理解できないのは、次のとおりです。 なぜ fstream
非常にしっかりと結合しています filebuf
, 、そのため filebuf
? ストリームとBUFを分離する全体のポイントは、異なるバッファーでストリームを使用できることです。
ソリューション:
=> filestream
の暗黙のインターフェイスに依存する必要があります filebuf
. 。つまり、FSTREAMはStreamBufクラスでテンプレートする必要があります。これにより、誰もが独自のStreambufサブクラスを提供することができます fstream
実装する限り filebuf
暗黙のインターフェイス。問題:テンプレートパラメーターを追加することはできません fstream
使用中にテンプレートセレクターを破壊するためです fstream
テンプレートテンプレートパラメーターとして。
=> filebuf
追加の属性がない純粋な仮想クラスである必要があります。そのため、すべてのファイル*ガベージを運ばずに継承できるように。
主題に関するあなたのアイデア?
解決
チェックアウト mapped_file の中に boost.iostreams 図書館。自分で使用したことはありませんが、必要なことをすでにしているようです。
編集:おっと、あなたの質問を読み直してください、そして私はあなたがこれを楽しみのためにやっているのを見ています。おそらく、boost.iostreamsからインスピレーションを引き出すことができますか?
他のヒント
IO Streamsの設計では、実際のストリームの機能のほとんど(Stream Buffersの機能とは対照的に)が実装されています std::basic_istream
, std::basic_ostream
, 、および彼らの基本クラス。 文字列とファイルのストリームクラスは、適切なタイプのバッファーを備えたストリームがインスタンス化されることを確認できるように、多かれ少なかれ便利なラッパーです.
ストリームを拡張したい場合は、 あなたはほとんど常にあなたに提供したいと思っています 独自のストリームバッファクラス, 、そして、あなた自身のストリームクラスを提供する必要はほとんどありません。 。
独自のストリームバッファタイプを作成したら、たまたま持っているストリームオブジェクトのバッファーにすることができます。または、あなたはあなた自身のクラスを導き出します std::basic_istream
, std::basic_ostream
, 、 と std::basic_iostream
ストリームバッファーをインスタンス化し、基本クラスに渡します。
後者はユーザーにとってより便利ですが、バッファーのインスタンス化(つまり、ストリームクラスのコンストラクター)のボイラープレートコードを書く必要があります。
あなたの質問に答えるために:前者は後者の作成を容易にするためにのみ存在するため、ファイルストリームとファイルバッファーは非常にしっかりと結合されています。ファイルストリームを使用すると、すべてを簡単に設定できます。
独自のストリームクラスを使用して、自分のストリームバッファーの構築をラップすることは問題ではありません。
fstream
それ自体は大きなクラスではありません。それは継承します basic_stream
すべてのサポートを提供するため <<
と >>
オペレーションには、専門化されたものが含まれています steambuf
それは初期化する必要があり、パラメーターをに渡すために対応するコンストラクターは streambuf
コンストラクタ。
ある意味では、テンプレートされたソリューションについて書いたことは問題ありません。しかし basic_stream
aに導き出すこともできます tcp_stream
例えば。その場合、のコンストラクター fstream
少し役に立たない。したがって、新しいものを提供する必要があります tcpstream
クラス、継承 basic_stream
コンストラクターが作成できる正しいパラメーターを使用して tcp_stream
. 。最終的には、何からも何も使用しません fstream
. 。これを作成します tcpstream
3つまたは4つの関数のみを書くことの問題です。
最終的に、あなたはから派生します fstream
本当の理由のないクラス。これにより、クラスの階層、不要なカップリングにさらに結合が追加されます。
の全体のポイント std::fstream
それは_f_ileベース std::stream
. 。あなたが普通のものが欲しいなら std::stream
あなたに裏打ちされています mmstreambuf
, 、次に、aを作成する必要があります mmstreambuf
そしてそれを渡します std::stream::stream(std::streambuf*)