🌻天国にいけるC++言語入門🌻 進化し続けるオブジェクト指向プログラミング ver3.2307
メンバ関数のオーバーライドを設定しても親クラスのメンバ関数が上書きされてなくなってしまうわけではありません
メンバ関数のオーバーライドを設定しても親クラスのメンバ関数が上書きされてなくなってしまうわけではありません
ソーラー「
今日は💖親クラス💖に仮想関数というものを設定してみたいと思います
仮想関数とは
親クラスから子クラスへとクラスの継承をおこなったとき
💖親クラス💖のクラス宣言内で
メンバ関数として設定しておく関数のことなんです」
マックス「仮想関数?
仮想の関数ってなんだ?」
ソーラー「まずは
親クラスのメンバ関数が
子クラスのメンバ関数によって
オーバーライドされるプログラムを実行してみたいと思います
そうですね😊🌻
オーバーライドとは
親クラスのメンバ関数
と
同じ名前の
子クラスのメンバ関数
を設定することでしたね
それでは
親クラスGameCharacterのクラス宣言
と
そのメンバ関数statusDataDisplay()の定義を以下のように設定してみます
👇
class GameCharacter {
public:
string name;
int HP;
int MP;
void statusDataDisplay();
};
void GameCharacter::statusDataDisplay() {
cout << name << "\n";
cout << "HP " << HP << "\n";
cout << "MP " << MP << "\n";
cout << "親クラスのメンバ関数statusDataDisplay()が実行されました" << "\n";
}
そして
親クラスGameCharacterを継承した
子クラスDragonのクラス宣言
と
そのメンバ関数
statusDataDisplay()の定義を以下のように設定してみます
class Dragon:public GameCharacter {
public:
int DP;//🌞ドラゴンポイントが設定されています
void statusDataDisplay();
};
void Dragon::statusDataDisplay() {
cout << name << "\n";
cout << "HP " << HP << "\n";
cout << "MP " << MP << "\n";
cout << "DP " << DP << "\n";
cout << " 子クラスのメンバ関数statusDataDisplay()が実行されました" << "\n";
}
マックス「
親クラスGameCharacterのメンバ関数は
statusDataDisplay()
で
親クラスGameCharacterを継承した
子クラスDragonとそのメンバ関数も
statusDataDisplay()
というわけだ
関数名が一緒だな
この状態で
Pokkyの子クラスDragon型のオブジェクト宣言
Dragon Pokky;
を実行し
子クラスDragon型のオブジェクトPokkyを生成し
Pokky.name = "ポッキー";
Pokky.HP = 15;
Pokky.MP = 5;
Pokky.DP = 7;
を実行
そして
子クラスDragon型のオブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay();
を実行すると
子クラスDragonのメンバ関数statusDataDisplay()の方の定義
👇
void Dragon::statusDataDisplay() {
cout << name << "\n";
cout << "HP " << HP << "\n";
cout << "MP " << MP << "\n";
cout << "DP " << DP << "\n";
cout << " 子クラスのメンバ関数statusDataDisplay()が実行されました" << "\n";
}
の
name
HP
MP
DP
に
Pokky.name
Pokky.HP
Pokky.MP
Pokky.DP
が代入された
cout << Pokky.name << "\n";
cout << "HP " << Pokky.HP << "\n";
cout << "MP " << Pokky.MP << "\n";
cout << "DP " << Pokky.DP << "\n";
cout << " 子クラスのメンバ関数statusDataDisplay()が実行されました" << "\n";
が実行されるんだろう」
そのことを示すプログラムはこちらです
👇
#include <iostream>
#include <string>//文字列を取り扱うためにヘッダファイル <string>をインクルードしています
using namespace std;
class GameCharacter {
public:
string name;
int HP;
int MP;
void statusDataDisplay();
};
void GameCharacter::statusDataDisplay() {
cout << name << "\n";
cout << "HP " << HP << "\n";
cout << "MP " << MP << "\n";
cout << "親クラスのメンバ関数statusDataDisplay()が実行されました" << "\n";
}
class Dragon:public GameCharacter {
public:
int DP;//🌞ドラゴン型のキャラクターに特有のドラゴンポイントが設定されています
void statusDataDisplay();
};
void Dragon::statusDataDisplay() {
cout << name << "\n";
cout << "HP " << HP << "\n";
cout << "MP " << MP << "\n";
cout << "DP " << DP << "\n";
cout << "子クラスのメンバ関数statusDataDisplay()が実行されました" << "\n";
}
int main() {
Dragon Pokky;
Pokky.name = "ポッキー";
Pokky.HP = 15;
Pokky.MP = 5;
Pokky.DP = 7;
Pokky.statusDataDisplay();
return 0;
}
プログラムの実行結果
ポッキー
HP 15
MP 5
DP 7
子クラスのメンバ関数statusDataDisplay()が実行されました
マックス「子クラスDragonのクラス宣言内には
親クラスGameCharacterのメンバ関数宣言
void statusDataDisplay();
が引き継がれているし
もともと
子クラスDragonのクラス宣言内には
子クラスDragonのメンバ関数宣言
void statusDataDisplay();
が設定されているので
子クラスDragonのクラス宣言内には
2つの
メンバ関数宣言
void statusDataDisplay();
が存在することになる
なので
子クラスDragon型のオブジェクトのメンバ関数
Pokky.statusDataDisplay();
を実行したとき
親クラスGameCharacterのメンバ関数statusDataDisplay()の定義
を用いられたものが実行されるのか?
子クラスDragonのメンバ関数statusDataDisplay()の定義
を用いられたものが実行されるのか?
わから~んにゃ~い
とおもったら
子クラスDragonのメンバ関数statusDataDisplay()の定義
を用いられたものが実行されるんだったな
前のエピソードでやったじゃないか
なんだ もう(´▽`*)
親クラスGameCharacterのメンバ関数statusDataDisplay()
と全く同じ名前の
子クラスDragonのメンバ関数statusDataDisplay()
を設定することを
メンバ関数のオーバーライド
というんだったな」
ソーラー「そうなんです😊
そして
メンバ関数のオーバーライドが機能してくるのは
💖Pokkyの子クラスDragon型のオブジェクト宣言💖
Dragon Pokky;
により生成された
子クラスDragon型のオブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay();
が実行されるときだけなんです
なぜかというと
親クラスGameCharacterのクラス宣言内には
子クラスDragonのメンバ関数
statusDataDisplay()
は存在しないので
Pokkyの親クラスGameCharacter型のオブジェクト宣言
GameCharacter Pokky;
により
親クラスGameCharacter型のオブジェクトPokkyを生成し
Pokky.name = "ポッキー";
Pokky.HP = 15;
Pokky.MP = 5;
(DPは子クラスDragonのメンバ変数なので
親クラスGameCharacter型のオブジェクトPokkyのメンバ変数
Pokky.DPは存在しません
ですので
Pokky.DP = 7;は実行できませんので注意してください)
Pokky.statusDataDisplay();
が実行されるときは
🌞必ず🌞
親クラスGameCharacterのメンバ関数statusDataDisplay()の方の定義
👇
void GameCharacter::statusDataDisplay() {
cout << name << "\n";
cout << "HP " << HP << "\n";
cout << "MP " << MP << "\n";
cout << "親クラスのメンバ関数statusDataDisplay()が実行されました" << "\n";
}
の
name
HP
MP
に
Pokky.name
Pokky.HP
Pokky.MP
が代入された
cout << Pokky.name << "\n";
cout << "HP " << Pokky.HP << "\n";
cout << "MP " << Pokky.MP << "\n";
cout << "親クラスのメンバ関数statusDataDisplay()が実行されました" << "\n";
が実行されることになります」
そのことを示すプログラムはこちらです
👇
#include <iostream>
#include <string>//文字列を取り扱うためにヘッダファイル <string>をインクルードしています
using namespace std;
class GameCharacter {
public:
string name;
int HP;
int MP;
void statusDataDisplay();
};
void GameCharacter::statusDataDisplay() {
cout << name << "\n";
cout << "HP " << HP << "\n";
cout << "MP " << MP << "\n";
cout << "親クラスのメンバ関数statusDataDisplay()が実行されました" << "\n";
}
class Dragon:public GameCharacter {
public:
int DP;//🌞ドラゴン型のキャラクターに特有のドラゴンポイントが設定されています
void statusDataDisplay();
};
void Dragon::statusDataDisplay() {
cout << name << "\n";
cout << "HP " << HP << "\n";
cout << "MP " << MP << "\n";
cout << "DP " << DP << "\n";
cout << " 子クラスのメンバ関数statusDataDisplay()が実行されました" << "\n";
}
int main() {
GameCharacter Pokky;
Pokky.name = "ポッキー";
Pokky.HP = 15;
Pokky.MP = 5;
Pokky.statusDataDisplay();
return 0;
}
プログラムの実行結果
ポッキー
HP 15
MP 5
親クラスのメンバ関数statusDataDisplay()が実行されました
ソーラー「
Pokkyの親クラスGameCharacter型のオブジェクト宣言
GameCharacter Pokky;
を実行したとき
親クラスGameCharacter型のオブジェクトPokkyのメンバ変数
Pokky.name
Pokky.HP
Pokky.MP
親クラスGameCharacter型のオブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay()
が生成されているので
Pokky.name = "ポッキー";
Pokky.HP = 15;
Pokky.MP = 5;
Pokky.statusDataDisplay();
を実行することができます
Pokky.statusDataDisplay();
が実行されると
親クラスGameCharacterのメンバ関数statusDataDisplay()の方の定義
👇
void GameCharacter::statusDataDisplay() {
cout << name << "\n";
cout << "HP " << HP << "\n";
cout << "MP " << MP << "\n";
cout << "親クラスのメンバ関数statusDataDisplay()が実行されました" << "\n";
}
の
name
HP
MP
に
Pokky.name
Pokky.HP
Pokky.MP
が代入された
cout << Pokky.name << "\n";
cout << "HP " << Pokky.HP << "\n";
cout << "MP " << Pokky.MP << "\n";
cout << "親クラスのメンバ関数statusDataDisplay()が実行されました" << "\n";
が実行されることになります
つまり
メンバ関数のオーバーライド(💖上書き💖)といっても
親クラスGameCharacterのメンバ関数statusDataDisplay()
は
子クラスDragonのメンバ関数statusDataDisplay()に
上書きされてなくなってしまったわけではないということなんです
ちゃんと残っていますね」
ぶーにゃん「にゃお~ん😸」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます