メンバ関数のオーバーライドを設定しても親クラスのメンバ関数が上書きされてなくなってしまうわけではありません

ソーラー「


今日は💖親クラス💖に仮想関数というものを設定してみたいと思います


仮想関数とは


親クラスから子クラスへとクラスの継承をおこなったとき


💖親クラス💖のクラス宣言内で


メンバ関数として設定しておく関数のことなんです」



マックス「仮想関数?


仮想の関数ってなんだ?」


ソーラー「まずは


親クラスのメンバ関数が


子クラスのメンバ関数によって


オーバーライドされるプログラムを実行してみたいと思います


そうですね😊🌻


オーバーライドとは


親クラスのメンバ関数

同じ名前の


子クラスのメンバ関数


を設定することでしたね


それでは



親クラス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()に



上書きされてなくなってしまったわけではないということなんです


ちゃんと残っていますね」


ぶーにゃん「にゃお~ん😸」





  • Twitterで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます

新規登録で充実の読書を

マイページ
読書の状況から作品を自動で分類して簡単に管理できる
小説の未読話数がひと目でわかり前回の続きから読める
フォローしたユーザーの活動を追える
通知
小説の更新や作者の新作の情報を受け取れる
閲覧履歴
以前読んだ小説が一覧で見つけやすい
新規ユーザー登録無料

アカウントをお持ちの方はログイン

カクヨムで可能な読書体験をくわしく知る