親クラスに仮想関数を設定する場合は子クラスで同じ名前のメンバ関数を設定しオーバーライドされる必要があります 

クラス宣言内のメンバ関数宣言にvirtualを設定するとそのメンバ関数は仮想関数となります

ソーラー「さて


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

親クラスGameCharacter型のオブジェクトのアドレス

あるいは

子クラスDragon型のオブジェクトのアドレス



子クラスDragon*(アスタリスク)型のポインタ変数には

子クラスDragon型のオブジェクトのアドレスのみを


代入することができました





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


子クラスDragon型のオブジェクトPokkyのアドレスを代入した場合には



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


->(アロー演算子)を用いた


pta->statusDataDisplay()



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


Pokky.statusDataDisplay()


の管理するメモリ領域にアクセスすることになります


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



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


によって


          🍋オーバーライドされていても🍋


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


子クラスDragon型のオブジェクトPokkyのアドレス&Pokkyを代入した場合については



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


->(アロー演算子)を用いた


pta->statusDataDisplay()




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


Pokky.statusDataDisplay()


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



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


->(アロー演算子)を用いた


pta->(親クラスGameCharacterから引き継いだ)メンバ変数


pta->name

pta->HP

pta->MP

pta->(親クラスGameCharacterから引き継いだ)メンバ関数


pta->statusDataDisplay()


でアクセスできるのは



子クラスDragon型のオブジェクトPokkyの(親クラスGameCharacterから引き継いだ)メンバ変数


Pokky.name

Pokky.HP

Pokky.HP

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


Pokky.statusDataDisplay()


の管理しているメモリとなります


pta->statusDataDisplay();


が実行されると


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


Pokky.statusDataDisplay();


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



つまり


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


子クラスDragon型のオブジェクトPokkyのアドレスを代入した場合には



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

==============================================

子クラスDragon型のオブジェクトPokkyの(親クラスGameCharacterから引き継いだ)メンバ変数


Pokky.name

Pokky.HP

Pokky.HP

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


Pokky.statusDataDisplay()

==============================================

の管理しているメモリのアドレスが代入されているような状態となります


ですので


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


->(アロー演算子)を用いた


pta->(親クラスGameCharacterから引き継いだ)メンバ変数


pta->name

pta->HP

pta->MP


pta->(親クラスGameCharacterから引き継いだ)メンバ関数


pta->statusDataDisplay()



子クラスDragon型のオブジェクトPokkyの(親クラスGameCharacterから引き継いだ)メンバ変数


Pokky.name

Pokky.HP

Pokky.HP

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


Pokky.statusDataDisplay()


の管理しているメモリ



アクセスすることになります



さあ みなさん(^_^)/


仕組みがわかったかな。」


てんC「は~い🌞」


マックス「まあまあだ😊」


ソーラー「それでは


あらためまして


ptaの💖親クラスGameCharacter*型💖のポインタ変数宣言


GameCharacter* pta;


によって作製された


親クラスGameCharacter*型のポインタ変数


pta



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


Dragon Pokky;


によって作製された


🍋子クラスDragon型🍋のオブジェクトPokkyのアドレス


&Pokky



pta=&Pokky;



代入された状態で


親クラスGameCharacter*型のポインタ変数ptaに


子クラスDragonのメンバ変数DPが用いられた


pta->DP=10;



親クラスGameCharacter*型のポインタ変数ptaに



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


オーバライドした


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


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

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の子クラスDragon型のオブジェクト宣言をおこなっています


GameCharacter* pta;


pta = &Pokky;


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

pta->HP = 15;

pta->MP = 5;

pta->DP = 7;


pta->statusDataDisplay();



return 0;

}



ビルド実行結果


重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態

エラー (アクティブ) E0135 class "GameCharacter" にメンバー "DP" がありません Project33 c:\Users\solarplexuss\source\repos\Project33\Project33\Source.cpp 60

エラー C2039 'DP': 'GameCharacter' のメンバーではありません。 Project33 c:\users\solarplexuss\source\repos\project33\project33\source.cpp 60


ソーラー「


重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態

エラー (アクティブ) E0135 class "GameCharacter" にメンバー "DP" がありません Project33 c:\Users\solarplexuss\source\repos\Project33\Project33\Source.cpp 60

エラー C2039 'DP': 'GameCharacter' のメンバーではありません。 Project33 c:\users\solarplexuss\source\repos\project33\project33\source.cpp 60


が表示されたね



今のプログラムでは


ptaの💖親クラスGameCharacter*型💖のポインタ変数宣言


GameCharacter* pta;


によって作製された


親クラスGameCharacter*型のポインタ変数


pta



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


Dragon Pokky;


によって作製された


🍋子クラスDragon型🍋のオブジェクトPokkyのアドレス


&Pokky



pta=&Pokky;



代入されています



親クラスGameCharacterのクラス宣言内には


メンバ変数宣言

string name;

int HP;

int MP;


メンバ関数宣言

void statusDataDisplay();


は設定されていても


メンバ変数宣言

int DP;


は設定されていないので


親クラスGameCharacter*型のポインタ変数に


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


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

pta->HP = 15;

pta->MP = 5;


pta->statusDataDisplay();


は実行できても


もちろん


pta->DP = 7;


を実行することはできません


そこで


プログラム内から


親クラスGameCharacter*型のポインタ変数


pta->に


子クラスDragonのメンバ変数DPが用いられた


pta->DP = 7;


取り除いたものを実行したら


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

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の子クラスDragon型のオブジェクト宣言をおこなっています


GameCharacter* pta;


pta = &Pokky;


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

pta->HP = 15;

pta->MP = 5;


pta->statusDataDisplay();



return 0;

}


プログラムの実行結果


ポッキー

HP 15

MP 5

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



ソーラー「でてきました


プログラムの実行結果に表示されている


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


により


親クラスGameCharacter*型のポインタ変数pta->にstatusDataDisplay()が用いられた


pta->statusDataDisplay();


の実行においては


親クラスGameCharacterのメンバ関数statusDataDisplay()の定義が用いられているのがわかります


このプログラムのように


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


子クラスDragonのメンバ関数statusDataDisplay()によって


オーバーライドされていたとしても


親クラスGameCharacter*型のポインタ変数ptaに子クラスDragon型のオブジェクト

Pokkyのアドレスを代入し


親クラスGameCharacter*型のポインタ変数ptaにアロー演算子を用いた


pta->statusDataDisplay()


を実行した場合


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


Pokky.statusDataDisplay()


に相当するものが実行されることになります



子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ関数


Pokky.statusDataDisplay()


に相当するものが実行されることはありません




つまり


親クラスGameCharacter*型のポインタ変数ptaにアロー演算子を用いた


pta->statusDataDisplay()



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


Pokky.statusDataDisplay()


の管理しているメモリ領域に


アクセスすることはできても


子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ関数


Pokky.statusDataDisplay()


の管理しているメモリ領域に


アクセスすることはできないというわけです」


てんC「このプログラムでは


親クラスGameCharacter


のメンバ関数宣言は


void statusDataDisplay();


子クラスDragon


のメンバ関数宣言も


void statusDataDisplay();


に設定されています。


メンバ関数statusDataDisplay()のオーバーライドが行われていますが


機能していないようです


もしかして


なにかしらの意味があって


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


メンバ関数statusDataDisplay()



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



子クラスDragonのクラス宣言内に設定する


オーバーライド


が設定されているのですか?」


ソーラー「そうなんです。


親クラスGameCharacter*型のポインタ変数


pta



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


のアドレス


&Pokky


が代入された状態で


pta->statusDataDisplay();


が実行されると


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


Pokkyに


親クラスGameCharacterから引き継いだメンバ関数


statusDataDisplay()


が用いられた


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


Pokky.statusDataDisplay()


に相当する命令文が実行されることになります。


ですが



親クラスGameCharacter型のメンバ関数


          statusDataDisplay()



子クラスDragon型のメンバ関数


           statusDataDisplay()


を設定したのですから


pta->statusDataDisplay();


が実行されるとき


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


Pokkyに


子クラスDragonの(親クラスGameCharacterから引き継いだ)メンバ関数


statusDataDisplay()


が用いられた


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


Pokky.statusDataDisplay()


に相当する命令文が実行されるのではなく


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


Pokkyに


子クラスDragonの(子クラスDragonに元から備わっている)メンバ関数


statusDataDisplay()



が用いられた


子クラスDragon型のオブジェクトPokkyの(子クラスDragonに元から備わっている)メンバ関数


Pokky.statusDataDisplay()


に相当するものが


実行されるようにしたいときもあるというわけです。


どのようなときにそのような状況が生じてくるか?


詳しくは


仮想関数がどのように用いられるかをHuman(人間)型のゲームキャラクターに相手のステータスデータを読み取るスキャンという能力を設定することを通して学んでみましょう


の章をご覧ください」


マックス「そんな場合があるのか?


絶っっ対ないだろう


(そんなことはありません(笑)、すぐに身近なところで出てきます)


そもそも


親クラスGameCharacter*型のポインタ変数ptaでは


💖親クラスGameCharacterから引き継いだメンバ関数💖


           statusDataDisplay()


をもちいた


pta->statusDataDisplay();


を実行できても


🍋子クラスDragonのメンバ関数🍋


           statusDataDisplay()


をもちいた


pta->statusDataDisplay();



は実行できないんじゃないか


だから


pta->statusDataDisplay();


が実行されるとき


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


Pokkyに


子クラスDragonの(親クラスGameCharacterから引き継いだ)メンバ関数


statusDataDisplay()


が用いられた


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


Pokky.statusDataDisplay()


に相当する命令文が実行されるのではなく


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


Pokkyに


子クラスDragonの(子クラスDragonに元から備わっている)メンバ関数


statusDataDisplay()



が用いられた


子クラスDragon型のオブジェクトPokkyの(子クラスDragonに元から備わっている)メンバ関数


Pokky.statusDataDisplay()


に相当するものが


実行されるなんてのは無理だろう




ソーラー「そうなんです。



今のプログラムのように


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


メンバ関数宣言


void statusDataDisplay();


子クラスDragonのクラス宣言内で


メンバ関数宣言


void statusDataDisplay();


が実行されているとします


このように


親クラスGameCharacterのクラス宣言内と子クラスDragonのクラス宣言内で


同じ名前のメンバ関数宣言


void statusDataDisplay();


が設定されているとします



また メンバ関数のオーバーライドのお話に戻りますが



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


Dragon Pokky;


を実行すると


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


Pokky


が生成されます。


そして


子クラスDragonに元から備わっているメンバ関数


statusDataDisplay()


が用いられた


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


Pokky.statusDataDisplay()


を実行することができます


もちろん


Pokky.statusDataDisplay();


が実行されると


子クラスDragonのメンバ関数


statusDataDisplay()


の定義がもちいられることになります。




           親クラスと子クラスで


            同じ名前のメンバ関数


             が設定されている


               イコール


          😊オーバーライドされていると😊


        子クラス型のオブジェクトを作製した際


         親クラスのメンバ関数でなく


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


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


           だけが実行できることになります。


          オーバーライドされた


親クラスのメンバ関数の定義が用いられるということはありません



ですが


そうなんですが


子クラスDragon*型でなく


親クラスGameCharacter*型のポインタ変数


pta



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


のアドレス


&Pokky


が代入された場合に


親クラスGameCharacter*型のポインタ変数


pta->statusDataDisplay();


が実行されたなら


子クラスDragonに元から備わっているメンバ関数statusDataDisplay()の定義が用いられた


pta->statusDataDisplay();

(Dragon.statusDataDisplay();)

が実行されるようにしたいというわけです。」


マックス「ふ~ん、


そんな場合があるのか?」




再び・・・  予告です


詳しくは


仮想関数がどのように用いられるかをHuman(人間)型のゲームキャラクターに相手のステータスデータを読み取るスキャンという能力を設定することを通して学んでみましょう


の章をご覧ください


そのような例が身近に登場してきます


                      solarplexussより

 




ソーラー「


そこで


そのためには


親クラスGameCharacterのクラス宣言


class GameCharacter {


public:

string name;

int HP;

int MP;


void statusDataDisplay();


};


内の


メンバ関数宣言


void statusDataDisplay();


virtualをつけて


virtual void statusDataDisplay();


として


親クラスGameCharacterのメンバ関数


statusDataDisplay()



          😊仮想関数😊


に設定します。



(😊無かったことにするという意味合いがあります 、(笑)😊)


そうすると


親クラスGameCharacter*のポインタ変数


pta



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


のアドレス


&Pokky

を代入して


pta->statusDataDisplay();


を実行すると


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


親クラスGameCharacterから引き継いだメンバ関数


statusDataDisplay()


が用いられた


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


Pokky.statusDataDisplay();


に相当するものが実行されるのではなく


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


Pokkyに


🍋子クラスDragonに元から備わっているメンバ関数🍋


statusDataDisplay()


が用いられた


子クラスDragon型のオブジェクトPokkyの(子クラスDragonに元から備わっている)メンバ関数


Pokky.statusDataDisplay();


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



そのことを示す次のプログラムをご覧ください。


#include <iostream>

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

using namespace std;


class GameCharacter {


public:

string name;

int HP;

int MP;


virtual void statusDataDisplay();//👈👈👈🌞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の子クラスDragon型のオブジェクト宣言をおこなっています


GameCharacter* pta;


pta = &Pokky;


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

pta->HP = 15;

pta->MP = 5;


pta->statusDataDisplay();



return 0;

}


プログラムの実行結果


ポッキー

HP 15

MP 5

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



マックス「プログラムの実行結果が


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


だったのが


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



入れ替わった!


virtualを設定しただけなのに


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


の代わりに


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


が表示されている!」



ソーラー「このように


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


メンバ関数宣言にvirtualを設定すると


そのメンバ関数は


仮想関数と呼ばれるものになります。



そして


親クラスGameCharacter*のポインタ変数


pta



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


のアドレス


&Pokky


を代入した状態で


pta->statusDataDisplay();


が実行されると


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


Pokkyに


仮想関数である


親クラスGameCharacterから引き継いだメンバ関数


virtual void statusDataDisplay()


が用いられた


pta->statusDataDisplay();


が実行されるのではなく


いいかえると


親クラスGameCharacterから引き継いだメンバ関数



virtual void statusDataDisplay()


が用いられた


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


Pokky.statusDataDisplay();


に相当するものが実行されるのではなく



        オーバーライドがおこり



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



🍋子クラスDragonに元から備わっているメンバ関数🍋


statusDataDisplay()


が用いられた


子クラスDragon型のオブジェクトPokkyの(子クラスDragonに元から備わっている)メンバ関数


Pokky.statusDataDisplay();


に相当するものが実行されることになります


         つまり


まとめると



親クラスGameCharacter*のポインタ変数


pta



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


のアドレス


&Pokky


を代入した状態で


pta->statusDataDisplay();


を実行した場合


通常できないはずの


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


子クラスDragonに元から備わっているメンバ関数が用いられた


Pokky.statusDataDisplay()


が実行されることになるんです


どう 😊




ただし


親クラスGameCharacterのメンバ関数


statusDataDisplay()



同じ名前の


子クラスDragonのメンバ関数


statusDataDisplay()


によってオーバーライドされている必要があります


そして



       🌞ここが重要なのですが🌞


たとえ


       💖仮想関数が設定されていても💖



親クラスGameCharacter*のポインタ変数


pta



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


のアドレス


&Pokky


が代入された場合は




親クラスGameCharacter*のポインタ変数


pta


にアロー演算子を用いた



pta->name

pta->HP

pta->MP



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


をオーバーライドしている


子クラスDragonのメンバ関数statusDataDisplay()の定義が用いられた


pta->statusDataDisplay()


を実行することはできますが



子クラスDragonに元から備わっているメンバ変数


DP


が用いられた


pta->DP



(もし設定されていれば)

子クラスDragonだけに元から備わっているメンバ関数



が用いられた


pta->子クラスDragonだけに元から備わっているメンバ関数


を実行することはできません


ですので


もし


プログラム内で


pta->に子クラスDragonのメンバ変数DPが用いられた


pta->DP


が記述されていると


ビルドエラーが表示されることになります



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

👇



#include <iostream>

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

using namespace std;


class GameCharacter {


public:

string name;

int HP;

int MP;


virtual void statusDataDisplay();//🌞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の子クラスDragon型のオブジェクト宣言をおこなっています


GameCharacter* pta;


pta=&Pokky;


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

pta->HP = 15;

pta->MP = 5;

pta->DP = 7;

pta->statusDataDisplay();



return 0;

}



プログラムの実行結果


エラー C2039 'DP': 'GameCharacter' のメンバーではありません。

エラー (アクティブ) E0135 class "GameCharacter" にメンバー "DP" がありません


ソーラー「このプログラムでも


Dragon Pokky;


GameCharacter* pta;


pta=&Pokky;


の実行により



親クラスGameCharacter*型のポインタ変数


pta



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


のアドレス


&Pokky


が代入されていますが




親クラスGameCharacter*のポインタ変数


pta


にアロー演算子を用いた


親クラスGameCharacterのメンバ変数


pta->name

pta->HP

pta->MP



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


をオーバーライドしている


子クラスDragonのメンバ関数statusDataDisplay()の定義が用いられた


pta->子クラスDragonのメンバ関数statusDataDisplay()


のみ


が実行できることになります


親クラスGameCharacter*のポインタ変数


pta


にアロー演算子を用いた


子クラスDragonのメンバ変数


pta->DP


を実行することはできません


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

pta->HP = 15;

pta->MP = 5;

pta->DP = 7;

pta->statusDataDisplay();

のうち


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

pta->HP = 15;

pta->MP = 5;

pta->statusDataDisplay();


は実行することができますが


pta->DP = 7;


は実行することができないので


ビルドエラーが表示されることになります」


マックス「まあ、そりゃそうだろう


なんてったって


ptaは


      💖親クラスGameCharacter*のポインタ変数💖


だからな


pta->


につづけて用いることができるのは


親クラスGameCharacterのメンバ変数


name

HP

MP


親クラスGameCharacterのメンバ関数


statusDataDisplay()


だけってわけだ


まあ


pta->statusDataDisplay();


が実行されると


親クラスGameCharacterのメンバ関数


statusDataDisplay()


は仮想関数に設定されているので


子クラスDragonのメンバ関数の定義がもちいられることになるがな


うひゃは なんか理解した」

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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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