仮想関数を使わなければHuman(人間)型のゲームキャラクターの相手のステータスデータを読み取るスキャンという能力は子クラス型オブジェクトの(親クラスの)メンバ変数のデータしか読み取れません

ソーラー「今度は


さらに


新たに


親クラスGameCharacterを継承した


子クラスElfのクラス宣言とそのメンバ関数statusDataDisplay()


を以下のように


設定し登場させてみたいと思います

👇


class Elf:public GameCharacter {

public:


int EP;//👈エルフ型のキャラクターだけに備わっているエルフポイントです

void statusDataDisplay();

//親クラスGameCharacterのメンバ関数statusDataDisplay()をオーバーライドしています

};



//👇🌞🌞🌞クラスElfのメンバ関数statusDataDisplay() の定義です🌞🌞🌞

void Elf::statusDataDisplay() {


cout << name << "\n";

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

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

cout << "EP " << EP << "\n";//🌞エルフポイントEPを表示しています

}


ソーラー「


親クラスGameCharacterを継承した子クラスDragon

につづいて


親クラスGameCharacterを継承した


この子クラスElfを追加して用いて


子クラスHuman型のキャラクターであるリリアーネが


子クラスDragon型のキャラクターである ポッキー


子クラスElf型のキャラクターである シルフィ


のステータスデータ


を読み取る


ことを表現したプログラムを実行してみましょう


そのプログラムはこちらです

👇



#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";


}



class Human :public GameCharacter {

public:

int TP;//👈Human(人間)型のキャラクターだけに備わっているテクニックポイントです

void statusDataDisplay();//🌞メンバ関数statusDataDisplay()のオーバーライドを行っています


void scanGameCharacterData(GameCharacter& a);


};


//👇🌞🌞🌞クラスHumanのメンバ関数statusDataDisplay() の定義です🌞🌞🌞

void Human::statusDataDisplay() {


cout << name << "\n";

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

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

cout << "TP " << TP << "\n";

}




//👇🌞🌞🌞クラスHumanのメンバ関数scanGameCharacterData(GameCharacter& a)の定義です🌞🌞🌞



void Human::scanGameCharacterData(GameCharacter& a) {

cout << "スキャン発動!" << "\n";

cout << name << "は" << a.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


a.statusDataDisplay();


}


class Dragon :public GameCharacter {

public:


int DP;//👈ドラゴン型のキャラクターだけに備わっているドラゴンポイントです

void statusDataDisplay();


};



//👇🌞🌞🌞クラスDragonのメンバ関数statusDataDisplay() の定義です🌞🌞🌞

void Dragon::statusDataDisplay() {


cout << name << "\n";

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

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

cout << "DP " << DP << "\n";

}



class Elf :public GameCharacter {

public:


int EP;//👈エルフ型のキャラクターだけに備わっているエルフポイントです

void statusDataDisplay();

//親クラスGameCharacterのメンバ関数statusDataDisplay()をオーバーライドしています

};



//👇🌞🌞🌞クラスElfのメンバ関数statusDataDisplay() の定義です🌞🌞🌞

void Elf::statusDataDisplay() {


cout << name << "\n";

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

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

cout << "EP " << EP << "\n";

}



int main() {


Human Lyliane;

Lyliane.name = "リリアーネ";

Lyliane.HP = 10;

Lyliane.MP = 5;

Lyliane.TP = 7;


Dragon Pokky;

Pokky.name = "ポッキー";

Pokky.HP = 20;

Pokky.MP = 3;

Pokky.DP = 2;


Elf Sylphy;

Sylphy.name = "シルフィ";

Sylphy.HP = 3;

Sylphy.MP = 18;

Sylphy.EP = 3;


Lyliane.scanGameCharacterData(Pokky);

Lyliane.scanGameCharacterData(Sylphy);

Lyliane.scanGameCharacterData(Lyliane);


return 0;

}


プログラムの実行結果


スキャン発動!

リリアーネはポッキーのスキャンを開始した

ステータスデータ

ポッキー

HP 20

MP 3

スキャン発動!

リリアーネはシルフィのスキャンを開始した

ステータスデータ

シルフィ

HP 3

MP 18

スキャン発動!

リリアーネはリリアーネのスキャンを開始した

ステータスデータ

リリアーネ

HP 10

MP 5


マックス「スキャンが発動し


リリアーネが


ポッキーとシルフィ


のステータスデータを読み取っている


ついでに


自分自身のステータスデータを読み取っている( ^ω^)・・・


おしゃれだな😊」


ソーラー「リリアーネ、絶好調だね


このプログラムでは


Lylianeの子クラスHuman型のオブジェクト宣言


Human Lyliane;


を実行し


Human(人間)型のゲームキャラクター リリアーネ


名前 リリアーネ

HP 10

MP 5

TP 7


子クラスHuman型のオブジェクトLylianeのメンバ変数

Lyliane.name

Lyliane.HP

Lyliane.MP

Lyliane.TP


Lyliane.name = "リリアーネ";

Lyliane.HP = 10;

Lyliane.MP = 5;

Lyliane.TP = 7;

と代入しています



次に


Pokkyの子クラスDragon型のオブジェクト宣言


Dragon Pokky;


を実行し


Dragon(ドラゴン)型のゲームキャラクター ポッキー


名前 ポッキー

HP 20

MP 3

DP 2  


子クラスDragon型のオブジェクトPokkyのメンバ変数


Pokky.name

Pokky.HP

Pokky.MP

Pokky.DP



Pokky.name = "ポッキー";

Pokky.HP = 20;

Pokky.MP = 3;

Pokky.DP = 2;

と代入しています


さらに


Silphyの子クラスElf型のオブジェクト宣言


Elf Silphy;


を実行し


Elf(エルフ)型のゲームキャラクター シルフィ


名前 シルフィ

HP 3

MP 18

EP 3


子クラスElf型のオブジェクトSilphyのメンバ変数

Silphy.name

Silphy.HP

Silphy.MP

Silphy.EP


Silphy.name = "シルフィ";

Silphy.HP = 3;

Silphy.MP =18;

Silphy.EP=3;


と代入しています




さあ、そして いよいよ


子クラスHuman型のオブジェクトLylianeのメンバ変数


Lyliane.scanGameCharacterData(Pokky);


の実行ですね


Lyliane.scanGameCharacterData(Pokky);


が実行されると


👇子クラスHumanのメンバ関数

scanGameCharacterData(GameCharacter& a)の定義



void Human::scanGameCharacterData(GameCharacter& a) {


cout << "スキャン発動!" << "\n";

cout << name << "は" << a.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


a.statusDataDisplay();


}



親クラスGameCharacter&型の参照変数宣言


         💖GameCharacter& a💖



       🍎子クラスDragon型のオブジェクトPokky🍎


が代入されます



この場合


親クラスGameCharacter&の参照変数aでは


子クラスDragon型のオブジェクトPokkyの(GameCharacter)メンバ変数


Pokky.name

Pokky.HP

Pokky.MP


子クラスDragon型のオブジェクトPokkyの(GameCharacter)メンバ関数


Pokky.statusDataDisplay()



の管理しているメモリ領域にのみアクセスすることができます


ですので


Lyliane.scanGameCharacterData(Pokky);


が実行されると


👇子クラスHumanのメンバ関数

scanGameCharacterData(GameCharacter& a)の定義



void Human::scanGameCharacterData(GameCharacter& a) {


cout << "スキャン発動!" << "\n";

cout << name << "は" << a.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


a.statusDataDisplay();


}




name にはLyliane.name

a.name にはPokky.name

が代入され

a.statusDataDisplay();

の部分は

Pokky.statusDataDisplay();

に等しいものが実行されることになります


つまり


cout << "スキャン発動!" << "\n";

cout << Lyliane.name << "は" << Pokky.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


Pokky.statusDataDisplay();


が実行されることになります



この


        💖Pokky.statusDataDisplay();💗


の実行においては



子クラスDragon型のオブジェクトPokkyの(GameCharacter)メンバ関数


Pokky.statusDataDisplay();


が実行されることになります


ですのでコマンドプロンプト画面に


スキャン発動!

リリアーネはポッキーのスキャンを開始した

ステータスデータ

ポッキー

HP 20

MP 3


が表示されることになります




次に


Lyliane.scanGameCharacterData(Silphy);


が実行されると



👇クラスHumanのメンバ関数scanGameCharacterData(GameCharacter& a)の定義



void Human::scanGameCharacterData(GameCharacter& a) {


cout << "スキャン発動!" << "\n";

cout << name << "は" << a.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


a.statusDataDisplay();


}



親クラスGameCharacter&の参照変数宣言


         💖GameCharacter& a💖



       🍎子クラスElf型のオブジェクトSilphy🍎


が代入されます



この場合


親クラスGameCharacter&の参照変数aでは


子クラスElf型のオブジェクトSilphyの(GameCharacter)メンバ変数


Silphy.name

Silphy.HP

Silphy.MP


子クラスElf型のオブジェクトSilphyの(GameCharacter)メンバ関数


Silphy.statusDataDisplay()



の管理しているメモリ領域にのみアクセスすることができます


ですので


Lyliane.scanGameCharacterData(Silphy);


が実行されると


👇クラスHumanのメンバ関数scanGameCharacterData(GameCharacter& a)の定義



void Human::scanGameCharacterData(GameCharacter& a) {


cout << "スキャン発動!" << "\n";

cout << name << "は" << a.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


a.statusDataDisplay();


}




name にはLyliane.name

a.name にはSilphy.name

が代入され

a.statusDataDisplay();

の部分は

Silphy.statusDataDisplay();

に等しいものが実行されることになります


つまり


cout << "スキャン発動!" << "\n";

cout << Lyliane.name << "は" << Silphy.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


Silphy.statusDataDisplay();


が実行されることになります



この


          💖Silphy.statusDataDisplay();💖


の実行においては



子クラスElf型のオブジェクトSilphyの(GameCharacter)メンバ関数


Silphy.statusDataDisplay();


が実行されることになります




ですので


コマンドプロンプト画面に


スキャン発動!

リリアーネはシルフィのスキャンを開始した

ステータスデータ

シルフィ

HP 3

MP 18


が表示されることになります



次に


Lyliane.scanGameCharacterData(Lyliane);


の実行ですね


Lyliane.scanGameCharacterData(Lyliane);


が実行されると



👇子クラスHumanのメンバ関数scanGameCharacterData(GameCharacter& a)の定義



void Human::scanGameCharacterData(GameCharacter& a) {


cout << "スキャン発動!" << "\n";

cout << name << "は" << a.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


a.statusDataDisplay();


}



親クラスGameCharacter&の参照変数宣言


         💖GameCharacter& a💖



       🍎子クラスHuman型のオブジェクトLyliane🍎


が代入されます



この場合


親クラスGameCharacter&の参照変数aでは


子クラスHuman型のオブジェクトLylianeの(GameCharacter)メンバ変数


Lyliane.name

Lyliane.HP

Lyliane.MP


子クラスHuman型のオブジェクトLylianeの(GameCharacter)メンバ関数


Lyliane.statusDataDisplay()



の管理しているメモリ領域にのみアクセスすることができます


ですので


Lyliane.scanGameCharacterData(Lyliane);


が実行されると


👇クラスHumanのメンバ関数scanGameCharacterData(GameCharacter& a)の定義



void Human::scanGameCharacterData(GameCharacter& a) {


cout << "スキャン発動!" << "\n";

cout << name << "は" << a.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


a.statusDataDisplay();


}




name にはLyliane.name

a.name にはLyliane.name

が代入され

a.statusDataDisplay();

の部分は

Lyliane.statusDataDisplay();

に等しいものが実行されることになります


つまり


cout << "スキャン発動!" << "\n";

cout << Lyliane.name << "は" << Lyliane.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


Lyliane.statusDataDisplay();


が実行されることになります



この


         💖Lyliane.statusDataDisplay();💖


の実行においては



子クラスHuman型のオブジェクトLylianeの(GameCharacter)メンバ関数


Lyliane.statusDataDisplay();


が実行されることになります


ですので


コマンドプロンプト画面に


スキャン発動!

リリアーネはリリアーネのスキャンを開始した

ステータスデータ

リリアーネ

HP 10

MP 5


が表示されることになりますね(^_-)-☆」


マックス「Oh,


どうやら


Human型のキャラクターは


他のキャラクターのステータスデータを


読み取る能力が設定されたみたいだな」


ソーラー「そうですね


ですが


ここで気付くことがあります」



マックス「ひょっとこ?気付くこと?」



ソーラー「詳しくは


もう1度

プログラムの実行結果をご覧ください」

👇

プログラムの実行結果


スキャン発動!

リリアーネはポッキーのスキャンを開始した

ステータスデータ

ポッキー

HP 20

MP 3

スキャン発動!

リリアーネはシルフィのスキャンを開始した

ステータスデータ

シルフィ

HP 3

MP 18

スキャン発動!

リリアーネはリリアーネのスキャンを開始した

ステータスデータ

リリアーネ

HP 10

MP 5



マックス「気付くこと???」



てんC「そういえば


Human型のキャラクター リリアーネは

Human型のキャラクター特有のステータスデータ

TP 7


Dragon型のキャラクター ポッキーは

Dragon型のキャラクター特有のステータスデータ

DP 2


Elf型のキャラクター シルフィは

Elf型のキャラクター特有のステータスデータ

EP 3


をもっているのですが


それが表示されていませんね



マックス「おおぅ ほんとだ


あれ?????


子クラスHumanの

親クラスGameCharacterのメンバ関数

statusDataDisplay()を

オーバーライドしているメンバ関数statusDataDisplay()の定義は


void Human::statusDataDisplay() {


cout << name << "\n";

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

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

cout << "TP " << TP << "\n";//🌞TPを表示します

}


なのにな


って



Lyliane.scanGameCharacterData(Lyliane);


が実行されると


以下の命令文が実行されることになるが

👇

cout << "スキャン発動!" << "\n";

cout << Lyliane.name << "は" << Lyliane.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


Lyliane.statusDataDisplay();

👆


この


        💖Lyliane.statusDataDisplay();💖


が実行されるときは


親クラスGameCharacterのメンバ関数statusDataDisplay()の定義


が用いられたものが実行されるんだろう


親クラスGameCharacterのメンバ関数statusDataDisplay()の定義

👇


void GameCharacter::statusDataDisplay() {


cout << name << "\n";

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

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


}


👆


name

HP

MP

Lyliane.name

Lyliane.HP

Lyliane.MP

が代入されたものが実行されるのだから


リリアーネ

HP 10

MP 5


が表示されるだけで


リリアーネの

ステータスデータ

TP 7


が表示されるわけがないってか・・・


まあ、そうなるよな


じゃあ


コマンドプロンプト画面に


リリアーネ

HP 10

MP 5

TP 7


を表示させるには


今のプログラムの


cout << "スキャン発動!" << "\n";

cout << Lyliane.name << "は" << Lyliane.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


Lyliane.statusDataDisplay();


の中の


Lyliane.statusDataDisplay();


が実行されるとき




親クラスGameCharacterのメンバ関数statusDataDisplay()の定義


が用いられた


子クラスHuman型のオブジェクトLylianeの(親クラスから引き継いだ)メンバ関数


Lyliane.statusDataDisplay();


でなく



子クラスHumanのオーバーライドしているメンバ関数statusDataDisplay()の定義


が用いられた


子クラスHuman型のオブジェクトLylianeの(子クラスに備わっている)メンバ関数


Lyliane.statusDataDisplay();



が実行されるようにすれば



👇子クラスHumanのオーバーライドしているメンバ関数statusDataDisplay() の定義の


void Human::statusDataDisplay() {


cout << name << "\n";

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

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

cout << "TP " << TP << "\n";

}


👆


name

HP

MP

TP

Lyliane.name

Lyliane.HP

Lyliane.MP

Lyliane.TP


が代入されたものが実行されるのだから


リリアーネ

HP 10

MP 5

TP 7


が表示されるんじゃないか?


ってどうやったら そんなことが可能なんだ??




Lyliane.scanGameCharacterData(Lyliane);


が実行されると


👇クラスHumanのメンバ関数scanGameCharacterData(GameCharacter& a)の定義



void Human::scanGameCharacterData(GameCharacter& a) {


cout << "スキャン発動!" << "\n";

cout << name << "は" << a.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


a.statusDataDisplay();


}


親クラスGameCharacter&型の参照変数 宣言


         💖GameCharacter& a💖



       🍎子クラスHuman型のオブジェクトLyliane🍎


が代入される


            

           !!が!!



         💖GameCharacter&型の参照変数 a💖


では



子クラスHuman型のオブジェクトLylianeの()メンバ変数


Lyliane.name

Lyliane.HP

Lyliane.MP


子クラスHuman型のオブジェクトLylianeの()メンバ関数


Lyliane.statusDataDisplay()


の管理するメモリ領域にしかアクセスすることはできないんんん・・・



ということは


Lyliane.scanGameCharacterData(Lyliane);


が実行されると


👇子クラスHumanのメンバ関数

scanGameCharacterData(GameCharacter& a)の定義



void Human::scanGameCharacterData(GameCharacter& a) {


cout << "スキャン発動!" << "\n";

cout << name << "は" << a.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


a.statusDataDisplay();


}




name にはLyliane.name

a.name にもLyliane.name

が代入され

a.statusDataDisplay();

Lyliane.statusDataDisplay();

が実行されることになるが


           💖Lyliane.statusDataDisplay();💖



子クラスHuman型のオブジェクトLylianeの()メンバ関数


Lyliane.statusDataDisplay()


を実行してしまうことになる




子クラスHuman型のオブジェクトLylianeの(statusDataDisplay())メンバ関数


Lyliane.statusDataDisplay()


が実行されることはないいぃぃ


んもぉう(´▽`*)


どうしたらいいのおん?」



ソーラー「ここで登場するのが



         😊仮想関数😊


なんです」


マックス「・・??って


ちょっとまったああ😊


今思いつきそうぅぅ


👇子クラスHumanのメンバ関数scanGameCharacterData(GameCharacter& a)の定義



void Human::scanGameCharacterData(GameCharacter& a) {


cout << "スキャン発動!" << "\n";

cout << name << "は" << a.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


a.statusDataDisplay();


}


引数となっている


GameCharacter& a



Human& a


に変えればいいんじゃないか?(*´▽`*)


やったか?



その場合



Lyliane.scanGameCharacterData(Lyliane);



が実行されると


👇子クラスHumanのメンバ関数scanGameCharacterData(Human& a)の定義



void Human::scanGameCharacterData(Human& a) {


cout << "スキャン発動!" << "\n";

cout << name << "は" << a.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


a.statusDataDisplay();


}



         💖Human& a💖



       🍎子クラスHuman型のオブジェクトLyliane🍎


が代入されるだろぉ


            

          もうそのまんま\(^o^)/いぇ~い




ということは


Lyliane.scanGameCharacterData(Lyliane);



が実行されると


👇子クラスHumanのメンバ関数scanGameCharacterData(Human& a)の定義



void Human::scanGameCharacterData(Human& a) {


cout << "スキャン発動!" << "\n";

cout << name << "は" << a.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


a.statusDataDisplay();


}



name にはLyliane.name

a.name にもLyliane.name

が代入され

a.statusDataDisplay();

Lyliane.statusDataDisplay();

を表すことになるが


Human& a



Lyliane


が代入されている状態では


aは子クラスHuman型のオブジェクトLylianeそのものであり


Lylianeは子クラスHuman型のオブジェクトなので


Lyliane.statusDataDisplay();


の実行においては


子クラスHumanの


親クラスGameCharacterのメンバ関数statusDataDisplay()

オーバーライドしている子クラスHumanのメンバ関数statusDataDisplay()の定義が用いられた



子クラスHuman型のオブジェクトLylianeの(《《親クラスGameCharacterのメンバ関数statusDataDisplay()

オーバーライドしている子クラスHumanの》》)メンバ関数


        😊Lyliane.statusDataDisplay()😊


が実行されることになる


すると


子クラスHumanのメンバ関数statusDataDisplay()の定義

👇


void Human::statusDataDisplay() {


cout << name << "\n";

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

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

cout << "DP " << DP << "\n";

}


👆


name

HP

MP

DP

Lyliane.name

Lyliane.HP

Lyliane.MP

Lyliane.DP


が代入されたものが実行されるのだから


リリアーネ

HP 10

MP 5

TP 7

が表示される💖


めでたし、めでたしってわけだ\(^o^)/ やあったなあっ😊

(嘘^^だよ~~ん)


子クラスHumanのクラス宣言内のメンバ関数宣言を

                👇ここです

void scanGameCharacterData(GameCharacter& a);

から              👇ここです 

void scanGameCharacterData(Human& a);



子クラスHumanのメンバ関数の定義を

                   👇ここです

void Human::scanGameCharacterData(GameCharacter& a) {

cout << "スキャン発動!" << "\n";

cout << name << "は" << a.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


a.statusDataDisplay();


}

から

                   👇ここです

void Human::scanGameCharacterData(Human& a) {

cout << "スキャン発動!" << "\n";

cout << name << "は" << a.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


a.statusDataDisplay();


}


に変更してプログラムを即実行だ!」



その時のプログラムはこちらです

👇


#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";


}



class Human :public GameCharacter {

public:

int TP;;//👈Human(人間)型のキャラクターだけに備わっているテクニックポイントです

void statusDataDisplay();//🌞親クラスGameCharacterのメンバ関数statusDataDisplay()をオーバーライドしています


void scanGameCharacterData(Human& a);


};


//👇🌞🌞🌞子クラスHumanのメンバ関数statusDataDisplay() の定義です🌞🌞🌞

void Human::statusDataDisplay() {


cout << name << "\n";

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

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

cout << "TP " << TP << "\n";

}




//👇🌞🌞🌞子クラスHumanのメンバ関数scanGameCharacterData(GameCharacter& a)の定義です🌞🌞🌞



void Human::scanGameCharacterData(Human& a) {

cout << "スキャン発動!" << "\n";

cout << name << "は" << a.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


a.statusDataDisplay();


}


class Dragon :public GameCharacter {

public:


int DP;;//👈ドラゴン型のキャラクターだけに備わっているドラゴンポイントです

void statusDataDisplay();


};



//👇🌞🌞🌞クラスDragonのメンバ関数statusDataDisplay() の定義です🌞🌞🌞

void Dragon::statusDataDisplay() {


cout << name << "\n";

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

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

cout << "DP " << DP << "\n";

}



class Elf :public GameCharacter {

public:


int EP;//👈エルフ型のキャラクターだけに備わっているエルフポイントです

void statusDataDisplay();

//親クラスGameCharacterのメンバ関数statusDataDisplay()をオーバーライドしています

};



//👇🌞🌞🌞クラスElfのメンバ関数statusDataDisplay() の定義です🌞🌞🌞

void Elf::statusDataDisplay() {


cout << name << "\n";

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

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

cout << "EP " << EP << "\n";

}



int main() {


Human Lyliane;

Lyliane.name = "リリアーネ";

Lyliane.HP = 10;

Lyliane.MP = 5;

Lyliane.TP = 7;


Dragon Pokky;

Pokky.name = "ポッキー";

Pokky.HP = 20;

Pokky.MP = 3;

Pokky.DP = 2;


Elf Sylphy;

Sylphy.name = "シルフィ";

Sylphy.HP = 3;

Sylphy.MP = 18;

Sylphy.EP = 3;


Lyliane.scanGameCharacterData(Pokky);

Lyliane.scanGameCharacterData(Sylphy);

Lyliane.scanGameCharacterData(Lyliane);


return 0;

}


プログラムの実行結果



エラー (アクティブ) E0434 型 "Human &" の参照 (const で修飾されていない) は型 "Elf" の値では初期化できません

エラー (アクティブ) E0434 型 "Human &" の参照 (const で修飾されていない) は型 "Dragon" の値では初期化できません

エラー C2664 'void Human::scanGameCharacterData(Human &)': 引数 1 を 'Elf' から 'Human &' へ変換できません。

エラー C2664 'void Human::scanGameCharacterData(Human &)': 引数 1 を 'Dragon' から 'Human &' へ変換できません。



マックス「おおおぅ 何でビルド実行できん!?」



ソーラー「それは


子クラスHumanのメンバ関数scanGameCharacterData(Human& a)の定義のように

👇

void Human::scanGameCharacterData(Human& a) {

cout << "スキャン発動!" << "\n";

cout << name << "は" << a.name << "のスキャンを開始した" << "\n";

cout << "ステータスデータ" << "\n";


a.statusDataDisplay();


}

👆

子クラスHumanのメンバ関数scanGameCharacterData(Human& a)の引数部分が


Human& a


に設定されていると


子クラスDragon型のオブジェクトPokky

子クラスElf型のオブジェクトSylphy


Human& a


に代入することができなくなってしまうからなんです


ですので



Human& a


子クラスDragon型のオブジェクトPokky

子クラスElf型のオブジェクトSylphy

を代入することができないのに



Lyliane.scanGameCharacterData(Pokky);

Lyliane.scanGameCharacterData(Sylphy);



を実行しようとすると


ビルドエラー


エラー (アクティブ) E0434 型 "Human &" の参照 (const で修飾されていない) は型 "Elf" の値では初期化できません

エラー (アクティブ) E0434 型 "Human &" の参照 (const で修飾されていない) は型 "Dragon" の値では初期化できません

エラー C2664 'void Human::scanGameCharacterData(Human &)': 引数 1 を 'Elf' から 'Human &' へ変換できません。

エラー C2664 'void Human::scanGameCharacterData(Human &)': 引数 1 を 'Dragon' から 'Human &' へ変換できません。



が表示されることになるんだね」




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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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