私もそれを理解していないことを認めます。のデフォルトのコンストラクターがまったく見つかりません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()
を見たとき...)init
badbit
とにかく:要約は次のとおりです。通常、有効なストリームバッファへのポインターを のコンストラクターに渡すことが望ましいですstd::ostream
が、それができない場合は、null ポインターを渡し、後で を使用して有効なポインターを設定することは完全に有効です
rdbuf()
。そして、そうでないと言う答えは単に間違っています。