C++では、親クラスで定義した関数を子クラスで「上書き」できる仕組みがあります。これをオーバーライドと呼びます。さらに、親クラス型のポインタや参照を通じて、実際には子クラスごとの動作を呼び分けられる性質を ポリモーフィズム(多態性) といいます。
ゲーム開発では「敵キャラごとに異なる攻撃方法を持たせる」などの場面で活用されます。
混同しやすいですが、この2つは全く別の仕組みです。
オーバーロード(overload):同じクラス内で、同じ名前でも「引数の型や数」が異なる関数を複数定義すること。関数を使いやすくする工夫。同名関数の引数違いの定義。
オーバーライド(override):親クラスの関数を子クラスで上書きすること。仮想関数
virtual
を使い、動作を差し替える。子クラスで関数上書き。
class 親クラス {
public:
virtual void 関数名();
};
class 子クラス : public 親クラス {
public:
void 関数名() override; // 上書き
};virtual
を付けると、オーバーライド可能になるoverride
を付けると、上書きしていることを明示できる// 19_enemy_override.cpp
#include <iostream>
using namespace std;
class Enemy {
public:
virtual void attack() {
cout << "敵が攻撃した!" << endl;
}
};
class Slime : public Enemy {
public:
void attack() override {
cout << "スライムが体当たりしてきた!" << endl;
}
};
class Goblin : public Enemy {
public:
void attack() override {
cout << "ゴブリンが棍棒を振り下ろした!" << endl;
}
};
int main() {
Enemy* enemies[2];
enemies[0] = new Slime();
enemies[1] = new Goblin();
for (int i = 0; i < 2; i++) {
enemies[i]->attack(); // ポリモーフィズム:同じ呼び出しで違う動作
}
for (int i = 0; i < 2; i++) {
delete enemies[i];
}
return 0;
}実行結果(例)
スライムが体当たりしてきた!
ゴブリンが棍棒を振り下ろした!
? 親クラス Enemy*
型でまとめても、実際には子クラスごとの動作が呼ばれる。
Character に speak()
を定義し、デフォルトでは「……」と表示するHero と Villain
(悪役)を作り、それぞれ違うセリフを speak() で表示するCharacter* の配列に Hero と
Villain を入れ、for文で speak() を呼ぶ// 19_character_override.cpp
#include <iostream>
using namespace std;
class Character {
public:
virtual void speak() {
cout << "……" << endl;
}
};
class Hero : public Character {
public:
void speak() override {
cout << "勇者:世界を救うのは僕だ!" << endl;
}
};
class Villain : public Character {
public:
void speak() override {
cout << "魔王:この世界は我のものだ!" << endl;
}
};
int main() {
Character* chars[2];
chars[0] = new Hero();
chars[1] = new Villain();
for (int i = 0; i < 2; i++) {
chars[i]->speak();
delete chars[i];
}
return 0;
}