某所の記事を読んでいくつか書いておこうと思いたち、気がついた順に。
static 変数やグローバル変数はゼロで初期化される
C++の変数はたぶん4種類あって、グローバル変数、ファイルスコープのスタティック変数、関数スコープのスタティック変数、自動変数の4つ。static修飾子のついたメンバ変数はグローバル変数の一種で、クラスのメンバ変数はそのクラスが何者であるかに寄る。
で。
自動変数以外は、デフォルトコンストラクタや初期化子を使って陽に初期化しない限りゼロで初期化される。ゼロって何だって話ではあるが、ビットパターンのゼロである。論理的なゼロではない。
boolとintを足してもよい。
3+(4<2)+(3==2)
という具合。boolのtrueは、整数への昇格で1になる。falseは0になる。
bool 型変数に対して ++, -- はできないんだが、+=1, -=1 はできる。禁止しても良かったと思うんだけど。
bool t[2]={ true, true }; bool f[2]={ false, false }; t[0] += 1; // ++ だとコンパイルエラー f[0] += 1; // ++ だとコンパイルエラー t[1] -= 1; // -- だとコンパイルエラー f[1] -= 1; // -- だとコンパイルエラー cout << "t=" << t[0] << ", " << t[1] << endl; // t=1, 0 cout << "f=" << f[0] << ", " << f[1] << endl; // f=1, 1
こんな感じ。加算の前に整数への昇格が発生し、加算の結果はゼロか否かで評価するというルールに従うと、こういう結果になる。
なんでもない構造体にもデフォルトコンストラクタがある
以下の通り:
struct foo{ int a; }; foo s0; // 初期化されない foo s1 = foo(); // デフォルトコンストラクタで初期化 foo s2(); // foo を返す関数の宣言 cout << s0.a << endl; // 不定 cout << s1.a << endl; // ゼロ cout << s2.a << endl; // コンパイルエラー
デストラクタもあるが、呼んでも何も起きない。int や double なんかにもある。
一貫性のためだけの不要なルールと思いきや、テンプレートを書くときに役に立ったりするところが侮れない。
今日はこんなところで。