🌻天国にいけるC++言語入門🌻 進化し続けるオブジェクト指向プログラミング ver3.2307
親クラスのメンバ関数がオーバーライドされていても親クラス&型の参照変数に子クラス型のオブジェクトを代入した場合は参照変数.子クラスのメンバ関数を使用することはできません
ロードは関係してこなくなります
親クラスのメンバ関数がオーバーライドされていても親クラス&型の参照変数に子クラス型のオブジェクトを代入した場合は参照変数.子クラスのメンバ関数を使用することはできません
ソーラー「
さらに
親クラス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()の定義を以下のように設定してみます
👇
(🌞🌞🌞親クラスGameCharacterのメンバ関数statusDataDisplay()と同じ関数名のstatusDataDisplay()
を
子クラスDragonのメンバ関数statusDataDisplay()として設定している
つまり
メンバ関数のオーバーライドがなされているところがポイントです🌞🌞🌞
親クラスGameCharacterのメンバ関数statusDataDisplay()
と
子クラス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 << " 子クラスのメンバ関数()が実行されました" << "\n";
}
次に
💖親クラスGameCharacter&型💖の参照変数宣言
GameCharacter& a;
によって作製された
親クラスGameCharacter&型の参照変数
a
に
Pokkyの子クラスDragon型のオブジェクト宣言
Dragon Pokky;
によって作製された
🍋子クラスDragon型🍋のオブジェクトPokky
が
GameCharacter& a= Pokky;
(参照変数宣言は初期化を同時に行う必要があります)
と
代入された状態で
親クラスGameCharacter&型の参照変数aに
子クラスDragonのメンバ変数DPが用いられた
a.DP=10;
親クラスGameCharacter&型の参照変数aに
子クラスDragonのメンバ関数statusDataDisplay()が用いられた
a.statusDataDisplay();
が実行できるかどうかを試してみたいと思います」
マックス「??
親クラスGameCharacter&型の参照変数aに
子クラスDragonのメンバ関数statusDataDisplay()が用いられた
a.statusDataDisplay();
が実行できるかどうか・・・か・・・?
子クラスDragonのメンバ関数statusDataDisplay()が用いられた・・・・・・???
親クラスDragonのメンバ関数statusDataDisplay()
でなく
子クラスDragonのメンバ関数statusDataDisplay()が用いられた
a.statusDataDisplay();
なのか・・・
微妙ぃ
なんか
さっきのエピソードと内容は全く同じなんじゃないか?
親クラスGameCharacterのメンバ関数statusDataDisplay()が
子クラスDragonのメンバ関数statusDataDisplay()
によって
オーバーライドされていても
子クラスDragonのメンバ関数statusDataDisplay()は
子クラスDragonのメンバ関数であることにかわりはない
確か なんだったか?
💖親クラスGameCharacter&型💖の参照変数宣言
GameCharacter& a;
によって作製された
親クラスGameCharacter&型の参照変数
a
に
Pokkyの子クラスDragon型のオブジェクト宣言
Dragon Pokky;
によって作製された
🍋子クラスDragon型🍋のオブジェクトPokky
が
GameCharacter& a= Pokky;
と
代入された場合
ほんとはそうでないんだが
もう もろに
💖親クラスGameCharacter&型💖の参照変数宣言
GameCharacter& a;
によって作製された
親クラスGameCharacter&型の参照変数
a
に
Pokkyの親クラスGameCharacter型のオブジェクト宣言
GameCharacter Pokky;
によって作製された
🍋親クラスGameCharacter型🍋のオブジェクトPokky
が
GameCharacter& a= Pokky;
と
代入されたと
かんがえれば
わかりやすくなるんだろう
🍋子クラスDragon型🍋のオブジェクトPokky
でなく
💖親クラスGameCharacter型💖のオブジェクトPokky
が
GameCharacter& a= Pokky;
と
代入されたとみなしたらわかりやすくなる感じだったよなあ
にゃお~~~~~ん
お~
親クラスGameCharacter
と
親クラスGameCharacterを継承した子クラスDragon
の違いはというと
子クラスDragon
は
親クラスGameCharacter
の
メンバ変数宣言
メンバ関数宣言
を引き継いでいるが
親クラスGameCharacter
は
子クラスDragonだけに備わっている
メンバ変数宣言
メンバ関数宣言
を引き継いでいないということだ
当然かいっ!って?
💖親クラスGameCharacter型💖のオブジェクトPokkyが管理しているメモリは
💖親クラスGameCharacter型💖のオブジェクトPokkyのメンバ変数
Pokky,name
Pokky.HP
Pokky.MP
と
💖親クラスGameCharacter型💖のオブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay()
が管理しているメモリとなる
💖親クラスGameCharacter型💖のオブジェクトPokky
が
GameCharacter& a= Pokky;
と
親クラスGameCharacter&型の参照変数aに代入されたなら
親クラスGameCharacter&型の参照変数
a
は
💖親クラスGameCharacter型💖のオブジェクトPokky
そのものとなるので
💖親クラスGameCharacter&型💖の参照変数aが管理しているメモリは
💖親クラスGameCharacter&型💖のオブジェクトPokkyのメンバ変数
Pokky,name
Pokky.HP
Pokky.MP
と
💖親クラスGameCharacter型💖のオブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay()
が管理しているメモリとなる
いいかえると
💖親クラスGameCharacter&型💖の参照変数aが管理しているメモリは
💖親クラスGameCharacter&型💖の参照変数aのメンバ変数
a,name
a.HP
a.MP
と
💖親クラスGameCharacter&型💖の参照変数aのメンバ関数
a.statusDataDisplay()
が管理しているメモリだけとなる
むはは
となると
もちろん
💖親クラスGameCharacter&型💖の参照変数aにドット演算子.を用いた
a.に
子クラスDragonのメンバ変数DPが用いられた
a.DP=10;
は実行できないんじゃないか?
もちろん
💖親クラスGameCharacter&型💖の参照変数aにドット演算子.を用いた
a.に
子クラスDragonのメンバ関数statusDataDisplay()が用いられた
a.statusDataDisplay();
も実行できないんじゃないか?
だいたい
💖親クラスGameCharacter&型💖の参照変数aは
親クラスGameCharacter型のオブジェクトPokkyをあらわすのなら
親クラスGameCharacter型のオブジェクトPokkyにドット演算子.を用いた
Pokky.に
子クラスDragonのメンバ変数DPが用いられた
Pokky.DP
なんて存在せんだろお
Pokky.DP
が存在しないなら
a.DP
も存在しないわけだ
親クラスGameCharacter型のオブジェクトPokkyにドット演算子.を用いた
Pokky.に
用いられるのは
🍹親クラスGameCharacter型のメンバ変数🍹だけだからな
Pokky.DPの管理するメモリ領域は存在しないな
それとは別に
もっというと
💖親クラスGameCharacter型💖のオブジェクト
が
💖親クラスGameCharacter&型💖の参照変数a
に代入されているので
a.statusDataDisplay();
の実行においては
親クラスGameCharacterのメンバ関数statusDataDisplay()の定義が用いられた
a.statusDataDisplay();
が実行されるんじゃないか
a.statusDataDisplay();
は
💖親クラスGameCharacter型💖のオブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay()
が管理しているメモリにアクセスするって感じになるわけだ
statusDataDisplay()が
子クラスDragonのクラス宣言内でオーバーライドされていることは
関係ないじゃん
」
( うふふ 勘がいいな・・・)
ソーラー「うおお・・・す、するどいぃ・・・
😊🐱🚀🐱👓🐱🐉🐱💻🐱🏍🤳」
ソーラー「それでは
あらためまして
💖親クラスGameCharacter&型💖の参照変数宣言
GameCharacter& a=Pokky;
によって作製された
親クラスGameCharacter&型の参照変数
a
に
Pokkyの子クラスDragon型のオブジェクト宣言
Dragon Pokky;
によって作製された
🍋子クラスDragon型🍋のオブジェクトPokky
が
GameCharacter& a= Pokky;
と
代入された状態で
親クラスGameCharacter&型の参照変数
a
に
子クラスDragonのメンバ変数DPが用いられた
a.DP=10;
が実行できるかどうか?
親クラスGameCharacter&型の参照変数
a
に
親クラスGameCharacterのメンバ関数statusDataDisplay()を
オーバライドした
子クラスDragonのメンバ関数statusDataDisplay()が用いられた
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";
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& a= Pokky;
a.name = "ポッキー";
a.HP = 15;
a.MP = 5;
a.DP = 7;
a.statusDataDisplay();
return 0;
}
ビルド実行結果
重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態
エラー (アクティブ) E0135 class "GameCharacter" にメンバー "DP" がありません
エラー C2039 'DP': 'GameCharacter' のメンバーではありません。
ソーラー「ビルドエラー
重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態
エラー (アクティブ) E0135 class "GameCharacter" にメンバー "DP" がありません
エラー C2039 'DP': 'GameCharacter' のメンバーではありません。
が表示されました
💖親クラスGameCharacter&型💖の参照変数宣言
GameCharacter& a;
によって作製された
親クラスGameCharacter&型の参照変数
a
に
Pokkyの子クラスDragon型のオブジェクト宣言
Dragon Pokky;
によって作製された
🍋子クラスDragon型🍋のオブジェクトPokky
が
GameCharacter& a= Pokky;
(参照変数宣言は初期化を同時に行う必要があります)
と
代入された場合においては
もしわかりにくいと感じられるなら
もう もろに(ほんとうのことではないですが)
💖親クラスGameCharacter型💖のオブジェクトPokky
が
GameCharacter& a=Pokky;
と
代入されたと考えるとわかりやすいです
そう仮定すると・・・
親クラスGameCharacterのクラス宣言内には
メンバ変数宣言
string name;
int HP;
int MP;
メンバ関数宣言
void statusDataDisplay();
は設定されていても
メンバ変数宣言
int DP;
は設定されていないので
a.name = "ポッキー";
a.HP = 15;
a.MP = 5;
a.statusDataDisplay();
は実行できても
もちろん
a.DP = 7;
を実行することはできません
そのため
ビルドエラー
が表示されているんだね
そこで
プログラム内から
参照変数aに
子クラスDragonのメンバ変数が用いられた
a.DP = 7;
を
取り除いたものを実行したら
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";
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& a= Pokky;
a.name = "ポッキー";
a.HP = 15;
a.MP = 5;
a.statusDataDisplay();
return 0;
}
プログラムの実行結果
ポッキー
HP 15
MP 5
親クラスのメンバ関数statusDataDisplay()が実行されました
ソーラー「親クラスGameCharacterのメンバ関数statusDataDisplay()が実行されました
が表示されました
a.statusDataDisplay();
の実行においては
親クラスのメンバ関数statusDataDisplay()の定義がもちいられているね😊
このプログラムでは
親クラスGameCharacter&型の参照変数aに
子クラスDragon型のオブジェクトPokkyを代入していますね
そこで
本当はそうではないですが
親クラスGameCharacter&型の参照変数aに
親クラスGameCharacter型のオブジェクトPokky
が代入されたと考えてみることにします
この場合
親クラスGameCharacterのメンバ関数statusDataDisplay()が
子クラスのメンバ関数statusDataDisplay()によって
オーバーライドされている場合でも
親クラスGameCharacter&型の参照変数aに
ドット演算子.を用いて
a.statusDataDisplay()
を実行した場合
a.statusDataDisplay()
は
親クラスGameCharacter型のオブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay()
の管理するメモリ領域にアクセスすることになります
ですので
a.statusDataDisplay()
の実行においては
親クラスGameCharacterのメンバ関数statusDataDisplay()の定義が用いられることになります
子クラスDragonのメンバ関数statusDataDisplay()の定義が用いられることはありません
」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます