私もそれを理解していないことを認めます。のデフォルトのコンストラクターがまったく見つかりませんstd::istream。双方向ストリームを作成する場合は、コンストラクターが何も初期化しないため、双方向ストリームが必要になると思いますstd::ios_base。コンストラクターは何も初期化しませんが、派生クラスはstd::ios_base::init明示的に呼び出す必要があります。そのコンストラクターで。std::istream多重継承が関係する場合 (つまり、クラスがとの両方から派生する双方向 IO
std::ostream)、最も派生したクラスだけが を呼び出すと予想しますstd::ios_base::init。( では
std::iostream、std::ios_base::initは 2 回呼び出されます。) 実は、標準で調べる前に、デフォルトのコンストラクターは保護されていると答えようとしていました。呼び出されなかったからです。std::ios_base::init派生クラスではなく直接使用すると、初期化されていないストリームが発生します。
とにかく、当面の問題には簡単な解決策があります。
std::ostream out( NULL );
また、後でシンクを設定する必要がある関数は、 の非 const バージョンでありrdbuf()、 ではありませんcopyfmt()。 rdbuf()を読み取り、 へのポインタを設定するために使用され、書式設定フラグをコピーしstreambufます
が、 へのポインタには触れません。copyfmt()streambuf
したがって、次のようなことができます。
std::ostream out( NULL );
// ...
std::filebuf fileBuffer;
if ( filenameGiven ) {
fileBuffer.open( filename.c_str(), std::ios_base::out );
}
if ( fileIsOpen() ) {
out.rdbuf( &fileBuffer );
} else {
out.rdbuf( std::cout.rdbuf() );
}
(私はこれをよくします。実際、ファイルに出力するか、std::cout.
編集:
rdbufさらに別の修正:呼び出しの非 const バージョンなclear()ので、そうする必要はありません。( を呼び出さずにこれを行ったことは知っていましたが、そのセットclear()を見たとき...)initbadbit
とにかく:要約は次のとおりです。通常、有効なストリームバッファへのポインターを のコンストラクターに渡すことが望ましいですstd::ostreamが、それができない場合は、null ポインターを渡し、後で を使用して有効なポインターを設定することは完全に有効です
rdbuf()。そして、そうでないと言う答えは単に間違っています。