Arantium Maestum

プログラミング、囲碁、読書の話題

Effective C++勉強メモ: Item 4 オブジェクトはちゃんと初期化しよう

第4項目抜けてた・・・

C++だとオブジェクトが自動的に初期化されないことも多いよ、明示的に初期化しよう、というお話。

初期化されていない変数の値を読もうとするのは未定義な動作を踏むことになる。プラットフォームによってはランタイムエラーなのか?

初期化されるかどうかは厳密なルールがあるにはあるが複雑すぎて覚えるのは推奨できないとのこと。大雑把に言うと、C由来の言語機能ではまず初期化されず(配列とか)C++特有の機能では初期化されることが多い(例えばVector)。とりあえず全部ちゃんと明示的に初期化しよう。

この項目の話題は三つ

  • メンバ・データじゃないビルトイン型
  • メンバ・データ
  • The order of initialization of non-local static objects defined in different translation units

最後のわけのわからないやつがこの章の肝。

メンバ・データじゃないビルトイン型

手動で初期化しよう。以上

メンバ・データ

コンストラクタで初期化しよう。以上

ただし代入じゃなくて初期化するのが大事。

The order of initialization of non-local static objects defined in different translation units

なんのこっちゃ?と思うがMeyersも思ったらしく、詳しく説明している。

  • defined in different translation units: 複数のソースファイルに記述されている
  • non-local static objects: static定義されているオブジェクトで、関数スコープにローカルでないもの

これらは、どの順番で初期化されるかはわからない。

例えばファイルシステムをオブジェクト化したものを使うコードの場合、一箇所でglobalスコープのstaticとして定義し、他のところではそのstaticオブジェクトを利用したくなる。が、その「他のところ」が別のソースファイル(実際にはもっと厳密な定義がある)な場合、そちらの方が先に初期化されてしまうことも十分に可能。globalスコープのstaticオブジェクトだと、初期化の順番を制御することはできない。

ということでそのオブジェクトを返す関数を作り、関数スコープにlocalなstaticオブジェクトにするのが正しい。関数を使わなければ初期化されず、初期化されるとしたら必ず関数が最初に使われる一回のみで、それ以降は同じstaticオブジェクトが返される。いわゆるSingleton Patternである。