前回の記事でC++標準ライブラリの入出力周りについて書きましたが、
そもそも入出力周りを調べようと思ったのはオリジナルの入出力クラスを作ってみようと思ったからです。
今回は、そのことについて書いてみようと思います。
最初はbasic_ostreamを派生させて作れば良いだろうと思っていたのですが、write関数がvirtualではないのでどうにもできず、色々と調べてみたところbasic_streambufというクラスの役割が分かった、ということです。
最後に一応オリジナルの入出力クラスの作り方を簡単に説明しておきます。簡単に、です。
まずはbasic_streambufを派生させた新しいクラスbasic_xxxstreamを用意し、xsputnとxgetnを実装します。
あとばbasic_ostreamのコンストラクタにbasic_xxxstreamへのポインタを渡せば後はそのままbasic_ostreamを使って入出力が行えるようです。
言葉だと分かり難いかもしれませんのでイメージが沸くようコード断片を書いてみます。
断片なので、コンパイルはできません。ご注意下さい。
#include <ostream> // basic_xxxstreamクラス定義。本当は他にもいくつか定義する必要のある関数があります。 template <class Elem, class Tr = char_traits<Elem> > class basic_xxxstream : public basic_streambuf<Elem, Tr> { virtual std::streamsize xsgetn(char_type* _Ptr, std::streamsize _Count) { return _buffer->sgetn(_Ptr, _Count); } virtual std::streamsize xsputn(const char_type* _Ptr, std::streamsize _Count) { return _buffer->sputn(_Ptr, _Count); } }; int main(void) { basic_xxxstream<char> xxx; basic_ostream<char> out(&xxx); // 後はoutを使って好きなようにデータを出力 out << 10; out << "hogehoge"; out.flush(); return 0; }
なんとなくイメージは沸きましたか?
コンパイル可能なコードにするためには、basic_streambufをもっと調べて他の必要な関数を書き足していって下さい。