もし、同じ関数名をもちいてさまざまな関数を表すことができたならどれほど便利でしょうか? それができればプログラム内のある関数を名称を変えることなく丸ごと別の関数におき変えることができます

親クラス型のオブジェクトのアドレスが代入された 親クラスアスタリスク型のポインタ変数を使って 親クラスのメンバ関数が用いられた 親クラス型のオブジェクトのメンバ関数に相当するものを実行してみます

ソーラー「さあ 先のエピソードでも登場してきましたが

👇

親クラス型のオブジェクトのアドレスが代入された


親クラスアスタリスク型のポインタ変数を使って


親クラスのメンバ関数が用いられた


親クラス型のオブジェクトのメンバ関数に相当するものを実行してみます

👆

について


学んでいこうよ😊」


マックス「


親クラス型のオブジェクトのアドレスが代入された


親クラスアスタリスク型のポインタ変数を使って


親クラスのメンバ関数が用いられた


親クラス型のオブジェクトのメンバ関数に相当するものを実行してみます


・・・か・・・


わかった!


親クラスが


登場するということは


親クラスから子クラスへ


クラスの継承が行われている状態で

👇

親クラス型のオブジェクトのアドレスが代入された


親クラスアスタリスク型のポインタ変数を使って


親クラスのメンバ関数が用いられた


親クラス型のオブジェクトのメンバ関数に相当するものを実行してみます


👆

ということなんだな。」


てんC「


さすがですっ😊


マックスさん💖」


マックス「ふはは


そうだろう、そうだろう


もっと  もっと


ほめて構わんぞ」


solarplexuss「超基本的なところをついてきた!」



ソーラー「それでは


まずは


親クラスGameCharacterのクラス宣言と


親クラス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";

}



と設定してみます



そして


子クラスDragonのクラス宣言と


そのメンバ関数useFireRecovery(GameCharacter& a)


の定義を

以下のように設定します

👇

class Dragon:public GameCharacter {


public:

void statusDataDisplay() ;


};



void Dragon::statusDataDisplay() {


cout << name << "\n";

cout << "HP " << HP << "\n";

cout << "MP " << MP << "\n";

cout << "子クラスのメンバ関数statusDataDisplay()が実行されました" << "\n";

}

👆

マックス「親クラスGameCharacter



子クラスDragon


定義内容の異なる


同じ名前のメンバ関数statusDataDisplay()


が設定されてるな?


なんでだ?


オーバーライドされることになるが・・・


まあいいか\(^o^)/」



ソーラー「


この状態で


親クラスGameCharacterのオブジェクト宣言


GameCharacter Pokky;



実行した後


生成される親クラスGameCharacter型のオブジェクトPokky



アドレス&Pokkyを


親クラスGameCharacter*(アスタリスク)型のポインタ変数宣言


GameCharacter* pta


によって作製されるポインタ変数


pta



pta=&Pokky;


を実行することにより


格納してみます


その後


アロー演算子->を用いて


pta->name = "ポッキー";

pta->HP = 15;

pta->MP = 5;

pta->statusDataDisplay();



実行すれば


親クラスGameCharacterのメンバ関数statusDataDisplay()が用いられた


親クラスGameCharacter型のオブジェクトPokkyのメンバ関数


Pokky.statusDataDisplay();


に相当するものが実行されるというわけです


つまり


Pokky.statusDataDisplay();


を実行しなくても


pta->statusDataDisplay();


実行すれば


プログラムの実行結果に


ポッキー

HP 15

MP 5

親クラスのメンバ関数statusDataDisplay()が実行されました




表示されるというわけです


そのプログラムはこちらになります」

👇


#include <iostream>

#include <string>//文字列を取り扱うためにヘッダファイル <string>をインクルードしています

using namespace std;


class GameCharacter {


public:

string name;

int HP;

int MP;


void statusDataDisplay();


//クラスGameCharacterにはuseFireRecovery(GameCharacter& a)を設定しません

};



void GameCharacter::statusDataDisplay() {


cout << name << "\n";

cout << "HP " << HP << "\n";

cout << "MP " << MP << "\n";

cout << "親クラスのメンバ関数statusDataDisplay()が実行されました" << "\n";

}




class Dragon:public GameCharacter {


public:


void statusDataDisplay();


};



void Dragon::statusDataDisplay() {


cout << name << "\n";

cout << "HP " << HP << "\n";

cout << "MP " << MP << "\n";

cout << " 子クラスのメンバ関数statusDataDisplay()が実行されました" << "\n";

}




int main() {


GameCharacter Pokky;

GameCharacter* pta;


//👆GameCharacter*型のポインタ変数ptaを作製しました


pta = &Pokky;

pta->name = "ポッキー";

pta->HP = 15;

pta->MP = 5;


pta->statusDataDisplay();


return 0;

}




プログラムの実行結果


ポッキー

HP 15

MP 5

親クラスのメンバ関数statusDataDisplay()が実行されました



マックス「やったな ソーラーよ


GameCharacter*型のポインタ変数ptaを使って


親クラスGameCharacterのメンバ関数


statusDataDisplay()が用いられたオブジェクトのメンバ関数


Pokky.statusDataDisplay();


に相当するものを実行できたな。」


ソーラー「ここでのおまけポイントは


プロトタイプオブジェクトであるドラゴン型のキャラクターポッキーのデータやふるまいを


GameCharacter型のオブジェクト宣言


GameCharacter Pokky;


によって生成されるGameCharacter型のオブジェクトPokkyで取り扱っているという点です


先のエピソードでは


クラスDragonとそのメンバ関数useFireRecovery(GameCharacter& a)の定義を

以下のように設定していました

👇


class Dragon :public GameCharacter {

public:

void useFireRecovery(GameCharacter& a);


};



void Dragon::useFireRecovery(GameCharacter& a) {

cout << name << "は灼熱のフレアを" << a.name << "に吐いた !" << "\n";

cout << a.name << "は灼熱のフレアを受け燃え上がった!" << "\n";


a.HP += 10;


cout << a.name << "の体力は10回復した" << "\n";


}





もちろん

GameCharacter型のオブジェクトPokkyでは


このDragon型のオブジェクトPokkyのように


よりきめ細かく


プロトタイプオブジェクトであるドラゴン型のキャラクターのデータやふるまいを


とりあつかうことができません


子クラスDragonの方が親クラスGameCharacterより


プロトタイプオブジェクトであるドラゴン型のキャラクターのデータやふるまいを


とりあつかうための


詳細な設計図になっているからです


ですが今のプログラムでは


説明のために


クラスDragonとそのメンバ関数statusDataDisplay()の定義は


以下のように簡単に設定されているんだよ


👇


class Dragon :GameCharacter {


public:


void statusDataDisplay();


};



void Dragon::statusDataDisplay() {


cout << name << "\n";

cout << "HP " << HP << "\n";

cout << "MP " << MP << "\n";

cout << " 子クラスのメンバ関数statusDataDisplay()が実行されました" << "\n";

}




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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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