子クラス型のオブジェクトは親クラス型のオブジェクトであり子クラス型のオブジェクトでもあります

親クラスアスタリスク*型のポインタ変数には親クラス型のオブジェクトのアドレス あるいは 子クラス型のオブジェクトのアドレスを代入することができます

ソーラー「前のエピソードで見てきたように


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

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


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

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


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


マックス「


int*型のポインタ変数には


int型の変数のアドレスを


float*型のポインタ変数には


float型の変数のアドレスを


代入することができるのに似ているな。」


てんC「大分、前のエピソードで


学んだことでしたね。」


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


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

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


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

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


代入できるわけですが・・・・・」




次のプログラムをご覧ください。


#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:


void statusDataDisplay2();


};



void Dragon::statusDataDisplay2() {


cout << name << "\n";

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

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

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

}




int main() {


GameCharacter Pokky;

//👆Pokkyの親クラスGameCharacter型のオブジェクト宣言をおこなっています


GameCharacter* pta;


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


pta = &Pokky;

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

pta->HP = 15;

pta->MP = 5;


pta->statusDataDisplay();


return 0;

}


プログラムの実行結果


ポッキー

HP 15

MP 5

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


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


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


GameCharacter* pta;


によって作製された


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


pta



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


GameCharacter Pokky;


によって作製された


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


&Pokky



代入されています。


ここで


面白い現象が起こるんだよぉ」


マックス「面白い現象?


イカが空を飛ぶのか?」


てんC「もしかして


|🐙《たこ

》が空を飛ぶのですか?」


ソーラー「いや、飛ばないんだけど・・・


ここでは・・


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


GameCharacter* pta;


によって作製された


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


pta



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


GameCharacter Pokky;


によって作製された


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


&Pokky



代入されています。




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


GameCharacter* pta;


によって作製された


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


pta



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


Dragon Pokky;


によって作製された


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


&Pokky



代入することもできるんです。」


マックス「はあ?


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


pta



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


Dragon Pokky;


によって作製された


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


&Pokky



代入することができるぅ??


ええと


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


pta



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


&Pokky


を代入できる??



子クラスDragon*型のポインタ変数


pta



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


&Pokky


を代入できるのまちがいじゃないか?



まるで


int*型のポインタ変数に


float型の変数のアドレスを代入するみたいなことを


いってないか?


なんでぇ」


ソーラー「何でもです🐁



なあんてね



親クラスGameCharacter型のオブジェクトには


子クラスDragon型のオブジェクトを代入することができましたね


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

👇

#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:


void statusDataDisplay2();


};



void Dragon::statusDataDisplay2() {


cout << name << "\n";

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

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

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

}




int main() {




GameCharacter AI;


AI.name = "未設定";

AI.HP = 0;

AI.MP = 0;




//👆AIの親クラスGameCharacter型のオブジェクト宣言をおこなっています


Dragon Pokky;

//👆Pokkyの子クラスDragon型のオブジェクト宣言をおこなっています



Pokky.name = "ポッキー";

Pokky.HP = 15;

Pokky.MP = 5;



AI = Pokky;

//👆🌞🌞🌞ここが最大のポイントです🌞🌞🌞

//👆🌞🌞🌞親クラスGameCharacter型のオブジェクトAIに🌞🌞🌞

//🌞🌞🌞子クラスDragon型のオブジェクトPokkyを代入しています🌞🌞🌞


AI.statusDataDisplay();


return 0;

}


ポッキー

HP 15

MP 5

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


ソーラー「


親クラスGameCharacter型のオブジェクトAIに


子クラスDragon型のオブジェクトPokkyを代入する


AI = Pokky;


を実行することにより


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


AI.name

AI.HP

AI.MP


Pokky.name

Pokky.HP

Pokky.MP


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


ですので


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

AI.name

AI.HP

AI.MP

格納されているデータを


AI.name = "未設定";

AI.HP = 0;

AI.MP = 0;


から


AI.name = "ポッキー";

AI.HP = 15;

AI.MP = 5;


に変更することができました・ね(^_-)-☆


そして


AI = Pokky;


が実行されて


親クラスGameCharacter型のオブジェクトAI に

子クラスDragon型のオブジェクトPokkyが代入されていても



AIは親クラスGameCharacter型のオブジェクトであることにかわりはありません


ですので


AI.statusDataDisplay();


を実行すると



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


void GameCharacter::statusDataDisplay() {


cout << name << "\n";

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

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

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

}




name

HP

MP


AI.name

AI.HP

AI.MP


が代入されたものが実行されるので


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


ポッキー

HP 15

MP 5

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


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



逆に



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


親クラスGameCharacter型のオブジェクトAI を


Pokky=AI;


のように代入することはできません



このとき


親クラスGameCharacter型のオブジェクトAI に

子クラスDragon型のオブジェクトPokkyを代入する


AI = Pokky;


が実行できるのは


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


親クラスGameCharacter型のオブジェクトでもあり

子クラスDragon型のオブジェクトであるからなのです



反対に


AI は


親クラスGameCharacter型のオブジェクトですが

子クラスDragon型のオブジェクトではありません


同様に



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


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


代入することもできるし


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


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


代入することができます」

















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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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