ストラウストラップのプログラミング入門(18) 第10章とドリル
『ストラウストラップのプログラミング入門』読書日記。
goyokiさんが、前回の日記に引用した箇所ついて、こんな感想をつぶやいてくださっていたので、メモメモ。
そうなのでしょうか。
C++の関数やクラスの分け方について、世の中的にどんな考え方のバリエーションがあり、何が正統派で、何が多数派なのか、自分はまだ分かっていません。とほほ。(まあ、量を読めば、たぶんそのうち分かるハズ。その日のためにメモ…)
さて、今日は10章「入力および出力ストリーム」の最後までです。ドリルも回答しました。
10章を読むと、簡単なファイル入出力が書けるようになります。
また、ユーザ定義の入力/出力演算子についての理解が進みます。9章を読んだ時点ではもやもやしていたので、「ユーザ定義の出力演算子は、JavaでtoStringメソッドをオーバーライドするようなものだろう」という理解で保留していました。10章を読んで、組み込み型に対応した汎用的な入出力ストリームを、ユーザ定義型に対応させてあげるという概念が、やっと分かりました。
ドリルでハマったところ
この本では、たとえば「(x,y)」というフォーマットの入力値を読み込む方法として、次のようなイディオムを紹介しています。
istream& operator>>(istream& is, Point& p) { char c_open; if(is >> c_open && c_open != '('){ is.unget(); is.clear(ios_base::badbit); return is; } // ☆ double x; double y; char c; // カンマ char c_close; // 閉じ括弧 is >> x >> c >> y >> c_close; if(is.fail() || c != ',' || c_close != ')'){ error("bad point"); // ★ eofを見ないと最後にここで死ぬ。 } p.x = x; p.y = y; return is; }
ファイルから入力値を得る場合、(上のコメントのとおり)ストリームの状態を見てファイルの末尾を判定しないと、最後に★の箇所でエラーになります。
if(is.eof()){ return is; }
というわけで、判定をテキトーな場所(上の☆の場所)に、ひとまず埋め込みました。
文法
- clear関数は、引数に渡した状態フラグ以外のフラグを解除する
ここでのclearは、取り除くという意味ではないんですね。(直感と逆で、最初なんじゃこりゃと思いました)
- exceptions関数は例外をスローする
本文には、次のコードがちょくちょく出てきます。
// 問題が発生した場合は、どこかでistに例外をスローさせる(istはistreamのオブジェクト)
ist.exceptions(ist.exceptions()|ios_base::badbit);
コードのどこに書いてもいいのか? 例外をスローできる状態フラグ(のOR演算)は、必要なだけ書いてよいのか? などなど、まだよく分からないので、このへんを読んでいます。
- ios::exceptions http://cplusplus.com/reference/iostream/ios/exceptions/
- 29.3 Catching Exceptions http://stdcxx.apache.org/doc/stdlibug/29-3.html