class hoge{ 〜 }; class hogehoge : public hoge { 〜 };とかすると,hogehogeはhogeのクラスの能力も持つのだすごい.
よくある例えだと,生物クラスの中に哺乳類クラスとか爬虫類クラスとか植物クラスがいる感じ
生物が必ず持つのはたとえば寿命とか質量とか体積とか?
対して哺乳類は他にも足の数とか手があるとかあるよね
ここで哺乳類クラスが生物クラスを継承してると,哺乳類独自のものに加えて生物クラスのメンバも使えるようになるよ!
class ikimono{ 〜 }; class honyurui : public ikimono { 〜 };
こんな感じ
たとえば,生物クラスでは移動方法(idou())を返す関数があるとする
生物クラスを継承した人クラスにも移動方法を返す関数があるとする
それらをikimonoのポインタ変数で一元的に扱う時
この結果,ミジンコも佐藤も移動するんだよーとアッピルしてくるが,実際は佐藤は二足歩行なんだよ
ということで,仮想関数を使ってやると曰く
と,ikimono(親クラス)の中のidou()(名前がかぶってる関数)の頭にvirtualをつけてやると,きちんと判別してくれる.
やったね!
生物クラスを継承した人クラスにも移動方法を返す関数があるとする
それらをikimonoのポインタ変数で一元的に扱う時
この結果,ミジンコも佐藤も移動するんだよーとアッピルしてくるが,実際は佐藤は二足歩行なんだよ
ということで,仮想関数を使ってやると曰く
「オブジェクトが基底クラスのポインタで示されている場合にも、オブジェクトの型の関数が(正しく)呼び出される関数」になるらしい.ここらへんはそういうものとして覚えるしかないのかな?
と,ikimono(親クラス)の中のidou()(名前がかぶってる関数)の頭にvirtualをつけてやると,きちんと判別してくれる.
やったね!
継承したクラスと派生クラスで同名同引数のメソッド(同シグニチャとかいうらしい)が必要になることがあるが、この時派生先クラスでそのメソッドを呼び出すと、派生先のメソッドが優先的に呼び出される。
関数のオーバーライドとは、日本語で書けば、関数の上書き、または、差し替えというべきものです。これは、クラスが継承されるときに、派生クラスで基本クラスのメンバ関数と同じシグニチャの関数を定義することによって行われます。通常シグニチャの同じ関数は、同じクラスのメンバ関数として定義したり、グローバル関数として定義すると二重定義エラーになってしまいますが、クラスが継承されているときには、その基本クラスと派生クラスで同じシグニチャの関数を定義できます。派生クラスを使用するときには、派生クラスのメンバ関数が優先的に使用されます。このことを、基本クラスのメンバ関数が、派生クラスのメンバ関数でオーバーロードされたと言うわけです。引用元:C++マニアック
派生クラスのインスタンスを基底クラスの変数に代入するとアップキャストされる
ので、気をつけること。
ポインタを使用すると、ポインタ自体は親クラスにアップキャストされるが実体はそのまま残るので回避できる
vector<>を使ってクラスのポインタを管理したいなというときがありましょう。
たとえば
↓のプログラムは
- 個人のid番号を管理する
- 個人のデータをvector型にまとめる
- print()が呼び出されるとid番号を出力する
という要件で作成した簡単なプログラムです。
個人ごとにオブジェクトを生成する必要性があるのかは甚だ疑問ですが、それをファイリングするように管理したいとしましょう。
わざわざ入れ物用のvectorデータに個人のオブジェクト自体をコピーするようにしてもいいのです。
しかし、より大規模なデータになってくると同じデータのためにメモリがとられるのは無意味なような気がします。
ので、ポインタで管理することにしましょう。
このとき、何人分のデータが入力されているかわからないのでイテレータを使って回します。
で、**itとして外したくなるんだけど
bohyoh.comより「C言語講座】演算子一覧表」
に記述している通り優先順位を見ると、*よりも.の方が優先順位が高いのでエラーとなる
よって、(**it)として外す。
って書いたけど、わざわざイテレータ使わなくても
のほうが単純でいいかも
コメントをかく