標準ストリームクラスの仮想基底クラスは、basic_ios<charT,Traits> です。C++ では、仮想基底クラスは最新の派生クラスで初期化されます。つまり、基底クラス basic_ios<charT,Traits> は、新しい odatstream クラスで初期化されます。現在、クラス basic_ios<charT,Traits> は唯一の公開コンストラクタであり、ストリームバッファまでのポインタが必要です。クラス basic_ios<charT,Traits> にはストリームバッファまでのポインタがあり、basic_ios オブジェクトの作成時に初期化する必要があるので、基底クラスに対するストリームバッファの提供方法を記述しておきます。それには次の 2 通りの方法があります。
ファイルと文字列のストリームクラスには、ストリームバッファデータメンバーがあり、各ストリームバッファにポインタを設定して、仮想基底クラスの初期設定値を監視しています。これらのクラスから派生させる場合は、ファイルや文字列のストリームのコンストラクタによって上書きされるため、新たなストリームバッファポインタを作成する必要はありません (階層のどこにあっても、仮想基底クラスは非仮想基底クラスより先に作成されます)。
template <class charT, class Traits=char_traits<charT> > class MyOfstream : public basic_ofstream<charT,Traits> { public: MyOfstream(const char* name) : basic_ios<charT,Traits>(streambufptr) , basic_ofstream<charT,Traits>(name) {} // . . . };
構築順序は次のとおりです。
basic_ios(basic_streambuf<charT,Traits>*) basic_ofstream(const char*) basic_ostream(basic_streambuf<charT,Traits>*) ios_base()
basic_ios のコンストラクタによって設定されたストリームバッファポインタは、basic_ofstream のコンストラクタによって上書きされます。
この矛盾を解決するために、クラス basic_ios<charT,Traits> には、公開コンストラクタ以外に限定公開のデフォルトコンストラクタがあります。このデフォルトのコンストラクタは、ストリームバッファポインタを必要としますが、何も処理しません。その代わり、限定公開の初期設定関数 basic_ios<charT,Traits>::init() があり、これは basic_ios<charT,Traits> から派生させた任意のクラスから呼び出すことができます。この関数の場合、basic_ios<> 基底クラスは、実際にストリームバッファを提供するストリームクラス (この例では、basic_ofstream<charT,Traits>) によって初期化され、限定公開の init() 関数が呼び出されます。
template <class charT, class Traits=char_traits<charT> > class MyOfstream : public basic_ofstream<charT,Traits> { public: MyOfstream(const char* name) : basic_ofstream<charT,Traits>(name) {} // . . . };
構築と初期化の順序は、次のとおりです。
basic_ios() basic_ofstream(const char*) basic_ostream() which calls: basic_ios<charT,Traits>::init(basic_streambuf<charT,Traits>*) ios_base()
ストリームクラスからの派生スキーマは、ストリームバッファに常にポインタを提供する必要があるという点で少し異なります。これは、ファイルや文字列のストリームクラスと異なり、ストリームクラスにストリームバッファがないためです。たとえば、出力ストリームから派生したクラスは、次のようになります。
template <class charT, class Traits=char_traits<charT> > class MyOstream : public basic_ostream<charT,Traits> { public: MyOstream(basic_streambuf<charT,Traits>* sb) : basic_ostream<charT,Traits>(sb) {} // . . . };
ストリームの作成に必要なストリームバッファを提供する方法は、次のようにいくつかあります。
basic_filebuf<char> strbuf; strbuf.open("/tmp/xxx"); MyOstream<char> mostr(&strbuf); mostr << "Hello world\n";
MyOstream<char,char_traits<char> > mostr(cerr.rdbuf()); mostr << "Hello world\n";
ここで、ストリームバッファは mostr と cerr が共有していることに注意してください (詳細は、13.3 節を参照してください)。
Copyright (c) 1998, Rogue Wave Software, Inc.
このマニュアルに関する誤りのご指摘やご質問は、電子メールにてお送りください。
OEM リリース, 1998 年 6 月