備忘録七では、派生クラス CMascot のプロトタイプを取り植えず定義してみました。
メインとなるのは、CImageWindow 基本クラスから派生する CMascot 派生クラスの定義になります。備忘録四のメモで取り上げた、プロシージャから指定された関数を基本クラスから派生クラスの同名の関数に委託する処理をvirtual指定することで成立させています。
[CMascot.h]
virtual void WmPaint(); // 仮想関数。実装は各子クラスの同名の関数に委託。
[cMascot.h]
void WmPaint();
基本クラスにvirtual指定がされていることで、マスコットには、マスコットクラスのWmPaint();が、バルーン(ふきだし)には、バルーンクラスのWmPaint();にそれぞれ処理が委託されるようになります。基本クラスのvirtual指定を取り払ってしまうと、(参考)http://wisdom.sakura.ne.jp/programming/cpp/cpp30.html のサイトの実験結果からの引用にあるように、
(以下引用)
この機能は、同名のメンバ名を持つクラス間で面白い現象が発生します
メンバ名が基本クラスと派生クラスで衝突している場合
クラスを明示しなかった場合は常に自分のクラスのメンバを優先しました
と、同様の結果になります。メインの多態性についてはこれぐらいで置いといて、
もうひとつここではサブとして、static なメンバ関数内に配置されているメンバ変数の取り扱いに関してとりあげておきます。
教本では、作成した複数の小窓を登録しておくMapコンテナが、staticなメンバ関数として定義されているウィンドウプロシージャの中で使われている都合上、staticで宣言されています。そのルールは知ってたんですが、実装の仕方を知らなかったんでここで散々エラーに悩まされました(確か外部リンクエラーがでたと思う)
static なメンバ変数の実装に関するルールに関しての説明はこちらを読んでいただければいいと思います。(参考)http://www.geocities.jp/ky_webid/cpp/language/019.html
ここに、静的メンバ変数を宣言した場合、その実体の定義をクラス定義の外側に記述しなくてはなりませんと、書いてあります。
試験的な変数をCMascot.h のCImageWindow に、
static int TestNumber; // テスト用
というメンバ変数を宣言してます。
で、
[CMascot.cpp]
// 静的メンバ変数の定義(★クラス外部で行う) int CImageWindow::TestNumber = 100;
と、いう形で実体の定義を行っています。
あとは、プロシージャ内でこのstaticなメンバ変数を呼び出して、値をログに書きだすテストを行っています。
尚、子クラスのオブジェクトは作りましたが、まだ CImageWindow::WndProc の WM_PAINT に子クラスのWmPaint(); に飛べって書いて無いので、それは次のv06e.lzh でやります。
コメント