6章: 仮想ストリームの使い方
- 6.1 特殊仮想ストリーム
- 6.2 単純な例
- 6.3 Windows クリップボードと DDE Streambuf
- 6.4 DDE の例
- 6.5 RWAuditStreamBuffer
- 6.6 まとめ
各 C++ コンパイラに付属の iostream 機能は、C++ の開発者に広く理解されている機能です。その利点には、ストリームへの挿入および抽出における型保証、新しい型への拡張性、およびストリームバイトのソースおよび宛先のユーザへの透過性があげられます。これらは、streambuf クラスによって設定されます。
ただし、iostream 機構には、数多くの制限があり、フォーマット機能が特に問題になります。例えば、ostream に倍精度のデータを挿入する場合、それをバイナリとして挿入するような型保証はありません。さらに、すべてのバイトソースと宛先が streambuf のモデルに適合するわけではありません。XDR など多くのプロトコルの場合、形式は本質的にバイトストリームに結び付けられていて、切り離すことができません。
Rogue Wave の仮想ストリーム機能は、ストリームの理想的なモデルを提供することによって、これらの制限を克服しており、形式やストリームモデムによって制約を受けることがありません。Rwvios クラスは仮想ストリームクラス階層のルートにあります。これは、標準ライブラリクラス ios と同様のインタフェースを持つ抽象基底クラスです。
class RWvios{
public:
virtual int eof() = 0;
virtual int fail() = 0;
virtual int bad() = 0;
virtual int good() = 0;
virtual int rdstate() = 0;
virtual int clear(int v = 0) = 0;
};
RWvios から派生したクラスは、これらの関数を定義します。
抽象基底クラス RWvistream と RWvostream は、Rwvios を継承しています。これらのクラスは、すべての基本的な組み込み型および組み込み型の配列に対して、operator<<()、put()、get() などの純粋仮想関数を宣言しています。
class RWvistream : public RWvios {
public:
virtual Rwvistream& operator>>(char&) = 0;
virtual Rwvistream& operator>>(double&) = 0;
virtual int get() = 0;
virtual Rwvistream& get(char&) = 0;
virtual Rwvistream& get(double&) = 0;
virtual Rwvistream& get(char*, size_t N) = 0;
virtual Rwvistream& get(double*, size_t N) = 0;
.
.
.
};
class RWvostream : public RWvios {
public:
virtual Rwvostream& operator<<(char) = 0;
virtual Rwvostream& operator<<(double) = 0;
virtual Rwvostream& put(char) = 0;
virtual Rwvostream& put(double) = 0;
virtual Rwvostream& put(const char*, size_t N) = 0;
virtual Rwvostream& put(const double*, size_t N) = 0;
.
.
.
};
RWvistream と RWvostream を継承したストリームは、ユーザにわかりやすい形式で、組み込みを特殊ストリームに格納するものです。
仮想ストリーム機能の基本的機能は、形式に関係なく仮想出力ストリームに組み込みを挿入したり、抽出したりすることにあります。つまり、空白類、コンマなどで出力をフォーマットする必要がないということです。つまり、「ここは倍精度です。都合のいい形式で保存して、戻して欲しいと言ったときにそれを正しい形式で取り出してください」と Rwvostream に効果的に指示しているわけです。
このクラスは、非常に強力で、使用する最終出力媒体または形式を一切知らなくても、ストリーム演算子を書いたり使用することができます。例えば、出力媒体はディスク、メモリ領域、あるいはネットワークのどれでもかまいません。さらに、バイナリ、ASCII、またネットワークパケットなど、どの形式にも対応しています。これらいずれの場合も、同じストリーム演算子を使用します。