プログラミング実習の受講生の皆さん、今回の実習では C++ の真骨頂とも言える「継承」と「ポリモーフィズム」を学びます。
これまでは「便利な C 言語」として C++ を使ってきたかもしれませんが、ここからは「オブジェクト指向」という強力な設計思想の核心に触れていくことになります。課題に取り組む前に、以下のポイントを整理しておきましょう。
プログラムが大規模になると、似たようなコードを何度も書く「重複」が最大の敵となる。
private と
protected
の違いを理解し、適切にカプセル化を維持できる。今回の範囲で最も重要な 3 つの概念を整理しよう。
既存のクラス(基底クラス)のメンバー変数や関数を、新しいクラス(派生クラス)へ引き継ぐ仕組みである。
基底クラスのポインタを経由して関数を呼んだ際、実際に指しているオブジェクト(派生クラス)の関数を呼び出すための仕掛けである。
virtual
キーワード一つで、コンパイラが自動的に「仮想関数テーブル」を作成し、適切な関数を呼び出してくれる。main
関数など)は相手が具体的な何のオブジェクトであるかを気にせずに「描画せよ
(draw)」という命令を送るだけで済む。これを動的結合
(dynamic binding) と呼ぶ。「同じメッセージ(関数呼び出し)を送っても、相手によって異なる振る舞いをする」という性質である。
実習中に陥りやすい罠がいくつかある。
private
メンバーへのアクセス制限
基底クラスで private
指定された変数は、たとえ「子供」である派生クラスからでも直接触ることはできない。
対策:
子クラスには許すが外からは隠したい場合は、protected
(プロテクテッド) を使おう。
コンストラクタの呼び出し順序
派生クラスのインスタンスを作る際、まず「親(基底)」が作られ、その後に「子(派生)」のコンストラクタが動く。初期化リストでの親の呼び出し方を忘れないようにしよう。
仮想デストラクタの付け忘れ
(重要!) 基底クラスのポインタで派生クラスのオブジェクトを
delete する場合、基底クラスのデストラクタに
virtual
が付いていないと、派生クラス側の後処理(メモリ解放など)が実行されず、メモリリーク
(memory leak) の原因になる。
(覚え方:親の遺言 (virtual)
がないと、子の片付けがされない)
次に取り組むべきこと:
まずは資料の [List 12.1] 〜 [List 12.3] を確認し、基本的な
car
クラスの動作を理解することから始めてください。準備ができたら、課題 12.1
の hybrid_car への拡張に進みましょう。