はじめに
C++の継承では、子クラス(派生クラス)は親クラス(基底クラス)のメンバ関数を引き継ぎます。しかし、時には「親クラスの機能を、子クラス独自の処理に**上書き(変更)**したい」という場面があります。
このように、親クラスから継承したメンバ関数の処理内容を、子クラスで再定義することを「オーバーライド (Override)」と呼びます。オーバーライドは、子クラスのオブジェクトが、親クラスから引き継いだ機能に加えて、独自の振る舞いを持つことを可能にします。
この記事では、関数のオーバーライドの基本的な方法を、RPGのキャラクターを例に解説します。
メンバ関数をオーバーライドするサンプルコード
このコードは、Character
(キャラクター)という親クラスと、それを継承した Player
(プレイヤー)という子クラスを定義します。親クラスの displayInfo
関数を、子クラスでオーバーライドして、表示するメッセージを変更します。
完成コード
#include <iostream>
#include <string>
using namespace std;
// --- 親クラス(基底クラス) ---
class Character {
protected:
string name = "名無し";
int hp = 100;
public:
void displayInfo() {
cout << "--- キャラクター情報 ---" << endl;
cout << "名前: " << name << endl;
cout << "HP: " << hp << endl;
}
void setStats(string n, int h) {
name = n;
hp = h;
}
};
// --- 子クラス(派生クラス) ---
class Player : public Character {
protected:
int attackPower = 10;
public:
// 親クラスのdisplayInfo関数をオーバーライド
void displayInfo() {
cout << "=== プレイヤー情報 ===" << endl;
cout << "名前: " << name << endl;
cout << "HP: " << hp << endl;
cout << "攻撃力: " << attackPower << endl;
cout << "====================" << endl;
}
void setAttackPower(int ap) {
attackPower = ap;
}
};
int main() {
// 子クラスのオブジェクトを作成
Player myPlayer;
myPlayer.setStats("勇者", 150); // 親クラスから継承した関数
myPlayer.setAttackPower(25); // 子クラス独自の関数
// オーバーライドされた関数を呼び出す
myPlayer.displayInfo();
return 0;
}
実行結果
=== プレイヤー情報 ===
名前: 勇者
HP: 150
攻撃力: 25
====================
コードの解説
void Player::displayInfo()
子クラスである Player
の中で、親クラス Character
の displayInfo
と全く同じ関数名、引数、戻り値の型で関数を再定義しています。これがオーバーライドです。
main
関数の中で myPlayer.displayInfo();
を呼び出すと、親クラスの displayInfo
ではなく、子クラスの displayInfo
が優先的に呼び出されます。これにより、親クラスのメンバ関数が持つ機能を、子クラスの独自の機能で上書きすることができます。
オーバーライドのルール
オーバーライドするには、親クラスの関数と、完全に同じシグネチャ(関数名、引数リスト、戻り値の型)で関数を定義する必要があります。
もし引数の型や個数が異なると、それはオーバーライドではなく、単なるオーバーロードとして扱われてしまいます。
オーバーライドとprotected
親クラス Character
のメンバ変数 name
と hp
は protected
で宣言されています。そのため、子クラスである Player
のメンバ関数 displayInfo
からは、これらのメンバに直接アクセスして利用することができます。
まとめ
今回は、C++の継承におけるメンバ関数のオーバーライドについて解説しました。
- オーバーライドとは、親クラスから継承したメンバ関数を、子クラスで**再定義(上書き)**すること。
- 親クラスの関数と完全に同じシグネチャで、子クラスに定義する。
- 子クラスのオブジェクトからは、オーバーライドした関数が優先して呼び出される。
オーバーライドは、親クラスの汎用的な機能を、子クラス独自の具体的な振る舞いにカスタマイズするための、オブジェクト指向の重要なテクニックです。