4

数日前、私は先読みstreambufを使用するサブクラスを作成するのが楽しいだろうと決めました。mmap私のSTL(SGI)がどのように実装され、が含まれているfilebufことに気づいたかを調べました。したがって、から継承することは問題外です。basic_filebufFILE*basic_filebuf

だから私はから継承しましたbasic_streambuf。それから私は自分mmapbufをfstreamにバインドしたかった。

私がしなければならない唯一のことはfilebuf...の暗黙のインターフェースをコピーすることだと思いましたが、それは明らかな間違いでした。SGIでは、basic_fstreamを所有していbasic_filebufます。を呼び出しbasic_filestream.std::::ios::rdbuf( streambuf* )ても、ファイルストリームはそれを完全に無視し、独自のを使用しfilebufます。

だから今、私は少し混乱しています...確かに、私は自分自身を作成することができます、mmfstreamそれは正確なコピー/貼り付けになりますfstreamが、それは実際にはDRY指向ではないように聞こえます。

私が理解できないのは、なぜfstreamこれほど緊密に結合されているので、 ?filebuf以外のものを使用できないのかということです。filebufストリームとbufsを分離することの全体的なポイントは、異なるバッファーを持つストリームを使用できることです。

ソリューション:

=>filestreamの暗黙のインターフェースに依存する必要がありますfilebuf。つまり、fstreamはstreambufクラスによってテンプレート化する必要があります。これにより、の暗黙的なインターフェイスfstreamを実装している限り、誰もが独自のstreambufサブクラスをに提供できるようになります。問題:テンプレートテンプレートパラメーターとして使用しているときにテンプレートセレクターが破損するため、にfilebufテンプレートパラメーターを追加できません。fstreamfstream

=>filebuf追加の属性のない純粋な仮想クラスである必要があります。そのため、すべてのFILE*ガベージを実行せずに継承できます。

このテーマに関するあなたの考えは?

4

4 に答える 4

11

IOストリームの設計では、(ストリームバッファの機能とは対照的に)実際のストリームの機能のほとんどは、、、およびそれらの基本クラスに実装されstd::basic_istreamstd::basic_ostreamいます。文字列およびファイルストリームクラスは、多かれ少なかれ便利なラッパーであり、適切なタイプのバッファを備えたストリームがインスタンス化されることを保証します

ストリームを拡張する場合は、ほとんどの場合、独自のストリームバッファクラスを提供する必要があり、独自のストリームクラスを提供する必要はほとんどありません。。

独自のストリームバッファタイプを取得したら、それを、たまたま持っている任意のストリームオブジェクトのバッファにすることができます。または、、、から独自のクラスを派生させます。これstd::basic_istreamによりstd::basic_ostreamstd::basic_iostreamストリームバッファがインスタンス化され、基本クラスに渡されます。
後者はユーザーにとってより便利ですが、バッファーのインスタンス化のためのボイラープレートコード(つまり、ストリームクラスのコンストラクター)を作成する必要があります。

あなたの質問に答えるために:前者は後者の作成を容易にするためにのみ存在するため、ファイルストリームとファイルバッファは非常に緊密に結合されています。ファイルストリームを使用すると、すべてを簡単に設定できます。
独自のストリームクラスを使用して独自のストリームバッファの構築をラップすることは問題ではありません。とにかくファイルストリームを渡す必要はなく、基本クラスへの(参照)のみを渡す必要があるためです。

于 2010-06-07T13:18:00.880 に答える
2

fstreamそれ自体は大きなクラスではありません。これは、から継承してすべてのおよび操作basic_streamのサポートを提供し、初期化する必要のある特殊なものと、パラメーターをコンストラクターに渡すための対応するコンストラクターを含みます。<<>>steambufstreambuf

ある意味で、テンプレート化されたソリューションについて書いたことは問題ありません。しかし、たとえばbasic_streamに導き出すこともできます。tcp_streamその場合、のコンストラクタはfstream少し役に立たない。したがって、コンストラクターがを作成できるようにするための正しいパラメーターをtcpstream継承して、新しいクラスを提供する必要があります。結局、からは何も使用しません。この新しい関数を作成するには、3つまたは4つの関数のみを記述します。basic_streamtcp_streamfstreamtcpstream

fstream結局、あなたは本当の理由なしにクラスから派生するでしょう。これにより、クラス階層にさらに結合が追加され、不要な結合が追加されます。

于 2010-06-07T12:53:36.720 に答える
2

Boost.Iostreamsライブラリのmapped_fileを確認してください。自分で使ったことはありませんが、すでに必要なことをしているようです。

編集:おっと、あなたの質問を読み直してください、そして私はあなたが楽しみのためにこれをしているのを見ます。おそらく、Boost.Iostreamsからインスピレーションを引き出すことができますか?

于 2010-06-07T13:45:43.540 に答える
1

の要点std::fstreamは、それが_F_ileベースであるということですstd::streamstd::streamに裏打ちされた普通のものmmstreambufが必要な場合は、を作成してmmstreambufに渡す必要がありますstd::stream::stream(std::streambuf*)

于 2010-06-07T13:03:46.267 に答える