(有)胡桃沢製作所 made in "naha"

トップページ > object > Lesson4



仮想関数


基本クラスへのポインタ

変数のアドレスをポインタに代入出来ることは、C言語でもやった通りです
実はオブジェクトも同じようなことが可能で

基本クラスのポインタを使うと、基本クラスだけでなく
派生クラスのオブジェクトをさすことが出来る

つまり、基本クラスのポインタに、派生クラスのアドレスを代入出来るわけです

Car* pcar;
RacingCar rccar1;
pCar = &rccar1;

1行目で基本クラスのポインタを宣言、2行目で作成した派生クラスのアドレスを、3行目で代入しています

ちなみに、ポインタからメンバ関数を呼び出すときは

pCar -> show();

と、アロー演算子を使います

何故か基本クラス

さて、ポインタからの関数呼び出しには1つ問題があります。それは

呼び出される関数は、ポインタの型に依存する

ということです
つまり

派生クラスで関数をオーバーライドしても、ポインタが基本クラスなら基本クラスの関数が呼び出される

わけです

そこで仮想関数

仮想関数は

virtual 基本クラスメンバ関数の宣言;

と宣言します
仮想関数にすると何が良いかと言うと

ポインタがさしているオブジェクトの型に応じて、適切なメンバ関数が呼び出される

つまり

ポインタは基本クラスだけど、入ってるオブジェクトが派生クラスだから派生クラスの関数を呼び出される

ようになります

抽象クラス


純粋仮想関数

純粋仮想関数とは

virtual メンバ関数の宣言 = 0;

のように、宣言の最後に"=0"という指定がついた仮想関数です
さらに、純粋仮想関数は内容を定義する必要がありません
この純粋仮想関数を1つでも持つクラスを抽象クラスと呼び

オブジェクトを作成することが出来ない

という性質を持ちます
なので

Car car1;

Car* pCar = new Car;

などが出来なくなります

抽象クラスからの派生

抽象クラスもクラスなので、派生クラスを派生させることが出来ます
ただし

抽象クラスの純粋仮想関数の内容を、派生クラスで定義してオーバーライドする

必要があります
そうしないと、派生クラスのオブジェクト化が出来ません

抽象クラスの存在理由

「それじゃあ抽象クラスって、何のためにあるの?」という疑問が出てきます
よ~く考えてください

                抽象クラスから派生するにはオーバーライドが必要

                                      ↓

        派生したクラスは、必ず純粋仮想関数と同じ名前のメソッドを持っている

                                      ↓

                それぞれのクラスに適したメンバ関数が呼ばれる

つまり、「ここは基本クラスの関数で、ここは派生の……」と考えることなくコードを記述できます