ストラウストラップのプログラミング入門(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演算)は、必要なだけ書いてよいのか? などなど、まだよく分からないので、このへんを読んでいます。