[[C++のiostream]] * C++のiostream感想-その3- [#q323808c] ** rdbuf の謎 [#zbaf087a] iostream やその派生クラスには rdbuf() const という公開メンバ関数があり、その戻り値は、その オブジェクトに結び付けられた streambuf または その派生クラスのオブジェクトへのポインタを返す。 ところが iostream には、もう一つ rdbuf(streambuf* sb); という公開メンバ関数があり、iostream オブジェクトに 結び付けられている streambuf のオブジェクトを 切り替えられる。 何が謎かと言うと、使い道というか意図というか、 そのあたりがわからない。普通に調べると、使い道の例題と しては例えば std::ofstream ofs("myfile.txt"); std::streambuf* sb = std::cout.rdbuf(ofs.rdbuf()); ..(std::cout に出力).. std::cout.rdbuf(sb); とすると、std::cout への出力を(途中からでも) myfile.txt へ 切り替えることができるということなのだが、本当にこのために 公開メンバ関数になっているのだろうか? この機能は、危険極まりないと思う。iostream は fstream の基底 クラスでもあるので、逆も可能。ただし、さすがに危険なので 派生クラスレベルからの呼び出しは隠蔽されているみたいではある。 でも基底クラスの公開メンバー関数であり、fstream が iostream を public 継承しているので、使おうと思えば使える(何が起こるか わからないので、試すなら自己責任で!) std::ofstream ofs("myfile.txt"); std::streambuf* sb = ofs.std::ostream.rdbuf(std::cout.rdbuf()); ..(ofs に出力).. ofs.std::ostream.rdbuf(sb); とすると運がよければ ofs への出力がコンソール画面に出るだろうが もし途中で ofs.is_open() など呼んだら、多分悲惨なことになる。 そもそも、最初の例でも std::cout へバッファを切り替えた後、 元へ戻す前に ofs.close() などとしたら、やはり悲惨なことになるだろう。 危険を承知で使えということかも知れないが、最初の例が理由で こんな危険な仕様になっているのだろうか?