仮想関数、純粋な仮想関数についてまとめる

「実験しよう」→「コードが分かりづらいなぁ...」→「ちょっと書き換えるか」→「コンパイル通らなくなった\(^o^)/」というよくある事態に陥ったので、ちょっとまとめて整理を試みる。いつもの通り自分用メモ。以下の本を中心に整理していきます。Javaを最初に勉強したからそっちをベースに考えてしまうんだろうな、ってところが多々見うけられる。

C++実践プログラミング

C++実践プログラミング

  • 作者: スティーブオウアルライン,Steve Oualline,望月康司,クイープ
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2003/09
  • メディア: 単行本
  • 購入: 6人 クリック: 70回
  • この商品を含むブログ (35件) を見る

仮想関数

p422付近。基底クラスの関数を派生クラスにも定義して呼び出そうとする。基底クラスを引数に取るような関数を書いていた場合に呼び出す順序が問題になってくる場合がある。つまり、下の表のような呼び出され方をするということである。virtualキーワードを付けて仮想関数にすると(僕が)思ったような挙動をしてくれる。

クラス型 メンバ関数の種類 検索順序
派生クラス 通常の関数 派生クラス→基底クラス
基底クラス 通常の関数 基底クラス
派生クラス 仮想関数 派生クラス→基底クラス

JavaとかはdefaultがC++でのvirtualが付いたような挙動だったと思うので、意図しない、挙動だったと思ってしまうんだろう、たぶん。

派生クラスで上書きしなければならない、という制約を与えたい

p427付近。Javaだとinterfaceだったかabstractクラスだったかにするとそれを実装or継承したものに必要な関数がなかった場合コンパイルのときに怒ってくれる。が、C++でそれをどうやって実現すればいいのよ知らなかった(おい)。C++だとこれを「純粋な仮想関数」というものを使うと実現することができる。「純粋な」というのは

virtual void send_it() = 0;
virtual int cost() = 0;

という風なものを指していて、「= 0」を付けると純粋な仮想関数であるようになるらしい(つまりコンパイル時に怒ってくれる...はず)。知らなかった、なるほど。純粋な仮想関数を1つ以上含んでいるようなクラスのことを抽象クラス、というそうです。