検証用のコードを用意しましたのでまずはクラス図を見てみましょう。
単純な継承関係のクラスを二つ用意しました。init()は仮想関数になっています。
つぎにソースを見てみましょう、用意したのは次のファイルです。
- main.cpp
- Character.h
- CharacterMonster.h
#ifndef _CHARACTER_H_ #define _CHARACTER_H_ #includeclass Character { public: // constructor Character() { this->init(); } // destructor ~Character() { // do nothing... } protected: virtual void init() { // 仮想関数で定義 printf("init Character\n"); } }; #endif
次にCharacterMonster.hです。
#ifndef _CHARACTER_MONSTER_H_ #define _CHARACTER_MONSTER_H_ #include "Character.h" class CharacterMonster : public Character { public: // constructor CharacterMonster() { // do nothing... } // destructor virtual ~CharacterMonster() { // do nothing... } protected: virtual void init() { // オーバーライド printf("init Character Monster\n"); } }; #endif
最後にmain.cppです。
#include "CharacterMonster.h" #includeinit()はオーバーライドされているのでこのプログラムを実行すると「init Character Monster」が表示されると思いきや「init Character」が表示されてしまいます。void main(void) { Character* character = new CharacterMonster(); delete character; printf("hit any key..."); while(getchar() == EOF){} }
ということでコンストラクタで仮想関数を呼び出しても意図した動作になりませんでした。
ちなみにinit()を純粋仮想関数にした場合は実体がないためリンクエラーとなります。
なのでinit()メソッドをいつも用意するようにしているのですけどinit()を呼び出すのを忘れたりもするんですよね、ケースバイケースなのかなぁ?。
0 件のコメント:
コメントを投稿