EffectiveC++改訂2版 35項〜44項

6章。
オブジェクト指向は実使用したことがないだけに、概念的な理解しかできていないと思う。今度Meyerの本でじっくり勉強しよう。Smalltalk勉強会もあることだし。。

35項

public継承の肝

  • public継承は、「その一種である」という関係[英語で言うと"is-a"を]を意味す

る。

  • 基底クラスの引数(あるいは基底クラスへのポインタや、基底クラスへのリファレンス)を取るすべての関数は、その代わりに派生クラスのオブジェクト(あるいは派生クラスへのポインタや派生クラスへのリファレンス)を受け取ることができる。

これ以外に

設計上の判断として、階層構造に余計なクラスを追加するのは、クラス間の継承関係を間違えるのと同じくらいまずい判断となりうる。

は気をつけようと思う。

36項

メンバ関数の3つの種類(純粋仮想関数、一般仮想関数、非仮想関数)

  • メンバ関数のインタフェースは常に継承される
  • 純粋仮想関数を宣言する目的は、派生クラスに関数のインタフェースだけを継承することである。
  • 一般仮想関数を宣言する目的は、派生クラスに関数のインタフェースとデフォルトの実装を継承させることである。
  • 非仮想関数を宣言する目的は、その関数のインタフェースおよびその強制的な実装を派生クラスに継承させることである。

未熟なクラス設計者が犯しがちなもっとも一般的な2つのミス

  • すべてのメンバ関数を非仮想宣言すること
  • すべてのメンバ関数を仮想関数とすること(virtual宣言してしまうこと)

37項

これは前項の非仮想関数の補足。その目的から、派生クラスでの再定義をしてはいけないということ。

38項

デフォルトパラメータの要点。

  • 仮想関数は動的に結合され、デフォルトパラメータは静的に結合される

これにより思わぬデフォルト引数が使用されることがある。

39項

ダウンキャストにまつわる話。

  • ダウンキャストを除去する最良の方法は、そのようなキャストを仮想関数の呼び出しに置き換えること。
  • ダウンキャストは dynamic_cast で行う。

あと if の条件式の中で変数が定義できるのは知らなかった。

if (SavingAccout *psa = dynamic_cast<SaveingAccount*>(*p)) {
  psa->creditInterest();
}

40項

"has-a" と "is-implemented-in-terms-of" の導入。

41項

継承とテンプレート

  • オブジェクトの型の違いによってクラスの関数のふるまいが変わる事が無いのであれば、クラスのコレクションはテンプレートを使って生成するべきである。
  • オブジェクトの型の違いによってクラスの関数のふるまいが変わるのであれば、くらすのコレクションには継承を使うべきである。

42項

private継承の話。

手持ちの手段のうちでprivate継承が最適な実装テクニックである場合には、ためらわずにこれを使うべきだ。
しかし同時に、より一般的には層を重ねるテクニックが好ましく、可能であればそれを採用すべきである。

43項

多重継承の話。これはとりあえずパスすることにした。

44項

本章のまとめ。

  • 共通の基底クラスは、共通の特徴を意味する
  • public 継承には「その一種である」という意味がある。
  • priavte継承には「それを実装手段とする]という意味がある。
  • 層を重ねることの意味は「それを持っている」か「それを実装手段とする」である。
  • 純粋仮想関数には、関数のインタフェースだけが継承されるという意味がある。
  • 一般仮想関数には、その関数のインタフェースとデフォルトの実装が継承されるという意味がある。
  • 非仮想関数には、その関数のインタフェースと強制的な実装が継承されるという意味がある。