Item 1:View C++ as a federation of languages. C++ はただの ”C のクラスがあるバージョン ” ではない → 例外安全 (29 項 ) 、テンプレート (41 項 ) 、オーバーロード等の導入によりデザインや目指すコードが 変化している プログラミング言語はあくまで言語 時と共に使い方が変わる。 ベースの 4 つのプログラム C C++ のほとんどが C から来ている。 C より良い方法 (2 項『 #define の ” 代わり “ 』や 13 項 ) 。 C++ の C 部 分は C の効率的なコードを適用する。 Object-Oriented C++ C++ のクラス部分。 Template C++ テンプレート (46 、 48 項 ) STL テンプレートライブラリの一種。多くのプログラマが使うときの Convention( 規則 ) があり、使い方が 決まっている。コンパイルができればいいという考え方は捨てた方がいい。 ex):vector 、 list 、 map おまけ Build-in type(char, int 等 ) は reference で関数に渡すより、 value で渡した方が早い。 ( 詳しくは 20 項 )
Item 2:Prefer consts, enums, and inlines to #defines. プリプロセッサ・・・コンパイラの前に一定の規則にしたがって処 理を加える。 #include や #define コンパイラ・・・人間の記述したソースコードを、機械語の羅列であ るオブジェクトコードに変換する #define VALUE 1 などで定義した変数などは symbol table にのらな いためコンパイル時にエラーがでてもその値だけが出たりして変数 がわからなくなる。デバッグが大変になる。 また、浮動小数点の固定値変数を定義する際は、 # defineだ とオブジェクトの大きさも 2 倍になる。 Const ならコピーしてオブ ジェクトに埋め込みしない ( プリプロセッサは変数を全て定義され た値に置き換えてオブジェクト生成 ) 。 → 解決法として const Value =1;
Item 2:Prefer consts, enums, and inlines to #defines. const char* const authorName = “Scott Meyers”; ポインタのアドレス固定と中身の固定。 String を使うほうがいい const std::string authorName(“Scott Meyers”); static の使い方部分 (p.5 がちょっと不明 ) クラス単位で持つ static な定数は宣言と定義はコンパイラに 依存する。 #define はクラスの定数としても使えない、カプセル化にも 使えない。
Item 2:Prefer consts, enums, and inlines to #defines. “enum hack” – 定数宣言時の初期化が許されない場合で配 列の初期化を要求された場合等に有効。 const の定数はアド レスを使えるが、 enum の定数はアドレスアクセスできな い。 つまり define に近い。参照とポインタを使わせたくないな ら enum を使う。 #define を使ってきた理由にマクロがある。 Inline とテンプ レートで代用 →const が使える。 プリプロセッサの #include と #ifdef/#ifndef はまだ使われる 価値がある。
Item 3:Use const whenever possible. タイトル通りどんなときでも可能な限り const を使う ( 超基 本、超大事 ) 。 ポインタの const は注意。 char *p = greeting; //non-const pointer, non-const data const char *p = greeting; //non-const pointer, const data char * const p = greeting; //const pointer, non-const data const char * const p= greeting; //const pointer, const data STL の iterator はポインターで作られており、 const な iterator は他のポインタを指すことは許されていない、 data は変えることができる。値を変えたくなければ const_iterator を呼ぶ。
Item 3:Use const whenever possible. p.10 わからん operator わかりやすい例 const のオブジェクトによって呼び出す関数を変えることができる (p.11) const のオブジェクトの中でも、そのオブジェクト内だけで使える変数 の値を変えたい場合は mutable を使う。内部内でしか使われない変数を 保持しており、他は const オブジェクトで問題ないときに有効。 const なメンバ関数と非 const なメンバ関数を用意し、実質同じ動作を する場合は const なメンバ関数を const_cast して const を外してやれば コードは半分にできる。 非 const メンバ関数から const メンバ関数を呼ぶのは安全。逆は駄目。
Item 4:Make sure that objects are initialized before they’re used. オブジェクト内のすべてのデータを、コンストラクタで初期化。 class A { A::A() : a(2) // こっちが初期化 { a = 2;// これは代入。 } private: int a; } 代入はコンストラクタが関数内にはいるときにすでにメモリを確保し ている分、重複して a を呼んでいる。 initialization list( メンバ初期化子リ スト ) を使う。 クラスの中のメンバは宣言されている上から順に初期化される。 initialization list は宣言の順番と一緒に書くべき。
Item 4:Make sure that objects are initialized before they’re used. static オブジェクトは使用される前に初期化を保証できないので注意。 static オブジェクトの参照を返す関数で対応する。 マルチスレッドではこれでも問題が残る。 static なオブジェクトは正直よくわからないので、デザインを気をつけ るということだけ覚えておく ( ごめんなさい ) 。