例は次のとおりです。
#include <iostream>
using namespace std;
class Father {
public:
void play() {
cout << "到KTV唱歌..." << endl;
}
};
class Son :public Father {
public:
void play() {
cout << "一起打王者吧!" << endl;
}
};
void party(Father **men, int n) {
for (int i = 0; i<n; i++) {
men[i]->play();
}
}
int main(void) {
Father father;
Son son1, son2;
Father* men[] = {
&father, &son1, &son2 };
party(men, sizeof(men) / sizeof(men[0]));
system("pause");
return 0;
}
出力は次のとおりです。
上の例では、親クラス ポインタにサブクラス ポインタが含まれています。サブクラス ポインタがサブクラス内のメソッドを呼び出すと失敗します。サブクラス内のメソッドを呼び出す代わりに、親クラス内の同じ名前のメソッドを呼び出します。
では、この問題を解決するにはどうすればよいでしょうか?
仮想関数を使用すると、この問題を解決できます。
class Father {
public:
virtual void play() {
cout << "到KTV唱歌..." << endl;
}
};
出力は次のとおりです。
これがポリモーフィズムです!このことから、ポリモーフィズムの本質は、
形式的には一般的な処理には統一された親クラスのポインタを使用します
が、実際の実行ではこのポインタがサブクラスのオブジェクトを指している場合があり、
形式的には本来は親クラスのメソッドを呼び出しますが、実際にはサブクラスの同名のメソッドを呼び出すことになります。
[注意]:
プログラムの実行時に、親クラス ポインタが親クラス オブジェクトまたはサブクラス オブジェクトを指している場合、形式的には区別できません。
ポリモーフィック メカニズムを通じてのみ、対応するメソッドを実行できます。
仮想関数の基本的な使用法:
仮想関数の定義:
関数の戻り値の型の前に virtual を使用し、
メンバー関数の宣言にのみ virtual を追加し、メンバー関数の実装には virtual を追加しないでください。
仮想関数の継承:
メンバー関数が仮想関数、そのサブクラス [派生クラス]、およびサブクラスのサブクラスとして宣言されている場合、継承されたメンバー関数も自動的に仮想関数になります。
この仮想関数をサブクラスで書き換える場合は、virtualと書く必要はありませんが、読みやすいvirtualと書くことをお勧めします!