🌻天国にいけるC++言語入門🌻 進化し続けるオブジェクト指向プログラミング ver3.2307
親クラス&型の参照変数に子クラス型のオブジェクトを代入するということは単純に親クラス型のオブジェクトを代入しているととらえることができます
親クラス*型のポインタ変数は親クラス型のオブジェクトの(親クラスの)メンバ変数、メンバ関数にしかアクセスできません たとえ親クラス*型のポインタ変数に子クラス型のオブジェクトのアドレスを代入したとし
親クラス&型の参照変数に子クラス型のオブジェクトを代入するということは単純に親クラス型のオブジェクトを代入しているととらえることができます
ソーラー「
前のエピソードで見てきたように
親クラス&型の参照変数には
親クラス型のオブジェクト
あるいは
子クラス型のオブジェクト
子クラス&型の参照変数には
子クラス型のオブジェクトのみを
代入することができました
では
親クラス&型の参照変数に
🌞子クラス型のオブジェクトが代入されたときの🌞
プログラムをご覧ください
👇
#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 statusDataDisplay2();
};
void Dragon::statusDataDisplay2() {
cout << name << "\n";
cout << "HP " << HP << "\n";
cout << "MP " << MP << "\n";
cout << "DP " << DP << "\n";
cout << " 子クラスのメンバ関数statusDataDisplay()2が実行されました" << "\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()が実行されました
ソーラー「このプログラムでは
aの💖親クラスGameCharacter&型💖の参照変数宣言
GameCharacter& a;
によって作製された
親クラスGameCharacter&型の参照変数
a
に
Pokkyの子クラスDragon型のオブジェクト宣言
Dragon Pokky;
によって作製された
🍋子クラスDragon型🍋のオブジェクトPokky
が
GameCharacter& a=Pokky;
(参照変数宣言は参照変数宣言と同時に初期化される必要があります
初期化されていなければプログラムの実行時エラーが表示されます)
と
代入されています。」
マックス「???
子クラスDragon&型の参照変数
a
に
Pokkyの子クラスDragon型のオブジェクト宣言
Dragon Pokky;
によって作製された
🍋子クラスDragon型🍋のオブジェクトPokky
が
Dragon& a=Pokky;
と
代入されているんじゃないのか?」
ソーラー「いいえ
💖親クラスGameCharacter&型💖の参照変数宣言
GameCharacter& a;
によって作製された
親クラスGameCharacter&型の参照変数
a
に
Pokkyの子クラスDragon型のオブジェクト宣言
Dragon Pokky;
によって作製された
🍋子クラスDragon型🍋のオブジェクトPokky
が
GameCharacter& a=Pokky;
(参照変数宣言は参照変数宣言と同時に初期化される必要があります
初期化されていなければプログラムの実行時エラーが表示されます)
と
代入されています。」
マックス「???
💖親クラスGameCharacter&型💖の参照変数宣言
GameCharacter& a=Pokky;
によって作製された
親クラスGameCharacter&型の参照変数
a
に
Pokkyの子クラスDragon型のオブジェクト宣言
Dragon Pokky;
によって作製された
🍋子クラスDragon型🍋のオブジェクトPokky
が
GameCharacter& a=Pokky;
(参照変数宣言は参照変数宣言と同時に初期化される必要があります
初期化されていなければプログラムの実行時エラーが表示されます)
と
代入された状態で
a.name = "ポッキー";
a.HP = 15;
a.MP = 5;
a.statusDataDisplay();
を実行したのか
親クラスGameCharacterのメンバ変数宣言
string name;
int HP;
int MP;
親クラスGameCharacterのメンバ関数宣言
void statusDataDisplay();
を
子クラスDragonのクラス宣言内に継承してはいるんだが・・・
子クラスDragonのクラス宣言内には
オーバーライドされている同じ名前のメンバ関数宣言
void statusDataDisplay();
があるだろう?
a.statusDataDisplay();
を実行すると
子クラスDragonのメンバ関数statusDataDisplay()の定義がもちいられて
プログラムの実行結果
ポッキー
HP 15
MP 5
子クラスのメンバ関数statusDataDisplay()が実行されました
が実行されるとおもうんだが・・・
プログラムの実行結果をみると・・・
a.statusDataDisplay();
を実行するときは
親クラスGameCharacterのメンバ関数statusDataDisplay()の定義がもちいられているじゃないか
???
🍋子クラスDragon型🍋のオブジェクト
Pokky
が
親クラスGameCharacter&型の参照変数
a
に
代入されたんだろう?
a.statusDataDisplay();
を実行するときは
子クラスDragonのメンバ関数statusDataDisplay()の定義がもちいられるんじゃないのか?
よくわからん?????」
ソーラー「そうですね
Pokkyの親クラスGameCharacter型のオブジェクト宣言
GameCharacter Pokky;
の実行によって
親クラスGameCharacter型のオブジェクトPokkyが作製された場合
親クラスGameCharacter型のオブジェクトPokkyのメンバ変数
Pokky.name
Pokky.HP
Pokky.MP
親クラスGameCharacter型のオブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay()
が生成されることになります
このとき
親クラスGameCharacter型のオブジェクトPokkyのメンバ変数
Pokky.name
Pokky.HP
Pokky.MP
が管理しているメモリ領域と
親クラスGameCharacter型のオブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域が存在していることになります
このとき
aの親クラスGameCharacter&型の参照変数宣言
GameCharacter& a=Pokky;
を実行して
親クラスGameCharacter&型の参照変数
a
を作製します
親クラスGameCharacter型のオブジェクトPokkyを
親クラスGameCharacter&型の参照変数
a
に
a=&Pokky;
と代入します
親クラスGameCharacter&型の参照変数
aにドット演算子.を用いた
a.name
a.HP
a.MP
a.statusDataDisplay()
は
親クラスGameCharacter型のオブジェクトPokkyのメンバ変数
Pokky.name
Pokky.HP
Pokky.MP
親クラスGameCharacter型のオブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay()
と
同じ働きをすることになりました
親クラスGameCharacter&型の参照変数
aにドット演算子.を用いた
a.name
a.HP
a.MP
a.statusDataDisplay()
は
親クラスDragon型のオブジェクトPokkyのメンバ変数
Pokky.name
Pokky.HP
Pokky.MP
が管理しているメモリ領域と
親クラスGameCharacter型のオブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
にアクセスすることになります
親クラスGameCharacter&型の参照変数aに
親クラスGameCharacter型のオブジェクトPokkyを
代入したので
親クラスGameCharacter&型の参照変数
aにドット演算子.を用いた
a.name
a.HP
a.MP
a.statusDataDisplay()
は
親クラスGameCharacter型のオブジェクトPokkyのメンバ変数
Pokky.name
Pokky.HP
Pokky.MP
が管理しているメモリ領域と
親クラスGameCharacter型のオブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
にアクセスすることになったわけです
つまり
親クラスGameCharacter型のオブジェクトPokkyのメンバ変数
Pokky.name
Pokky.HP
Pokky.MP
が管理しているメモリ領域と
親クラスGameCharacter型のオブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
を管理しているのが
親クラスGameCharacter型のオブジェクトPokky
で
親クラスGameCharacter型のオブジェクトPokkyを格納するのが
親クラスGameCharacter&型の参照変数aなんです
もっといえば
親クラスGameCharacter型のオブジェクトPokkyのメンバ変数
Pokky.name
Pokky.HP
Pokky.MP
が管理しているメモリ領域と
親クラスGameCharacter型のオブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
は
あるメモリ領域を占有しています」
マックス「お、おもしろいな・・・😊
それは当たり前のことすぎるんじゃないか?」
ソーラー「ここがとても重要なポイントなんです
親クラスGameCharacter型のオブジェクトPokkyのメンバ変数
Pokky.name
Pokky.HP
Pokky.MP
が管理しているメモリ領域と
親クラスGameCharacter型のオブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
は
あるメモリ領域を占有していますが
それらのメモリをまとめて
ある変数が管理しているととらえると
その変数を格納する
その変数&型の参照変数も
登場してくることになります」
マックス「まあ、そうなるんじゃないか?」
ソーラー「このことはのちに生きていくことになるんだ
みんな おぼえておいてほしいな」
マックス「なんだ・・・
べつにそんなに特別の話でもないような・・
オーソドックスなパターンじゃないか
親クラスGameCharacter&型の参照変数aは
親クラスGameCharacter型のオブジェクトPokkyのメンバ変数
Pokky.name
Pokky.HP
Pokky.MP
が管理しているメモリ領域と
親クラスGameCharacter型のオブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
にアクセスできるってわけだ」
ソーラー「そうなんです
それとは別に
Pokkyの🍋子クラスDragon型🍋のオブジェクト宣言
Dragon Pokky;
の実行によって子クラスDragon型のオブジェクトPokkyが作製された場合
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ変数
Pokky.name
Pokky.HP
Pokky.MP
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
さらに
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ変数
Pokky.DP
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ関数
Pokky.statusDataDisplay()
が生成されることになります」
マックス「さっきの場合より
この部分が
👇
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ変数
Pokky.DP
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ関数
Pokky.statusDataDisplay()
👆
が増えた感じだな」
ソーラー「そうなんです
Pokkyの💖親クラス型GameCharacter型💖のオブジェクト宣言
GameCharacter Pokky;
を実行して
親クラス型GameCharacter型のオブジェクトPokkyを作製した場合と
Pokkyの🍋子クラスDragon型🍋のオブジェクト宣言
Dragon Pokky;
を実行して
子クラス型Draon型のオブジェクトPokkyを作製した場合の違いってわけなんです
このとき
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ変数
Pokky.name
Pokky.HP
Pokky.MP
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
と
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ変数
Pokky.DP
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ関数)
Pokky.statusDataDisplay()
が管理しているメモリ領域が
存在していることになります
🌞同じ名前の🌞
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
と
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ関数
Pokky.statusDataDisplay()
が
生成されているところが
🌞ポイントです🌞
🌞同じ名前だけど2つの異なる🌞
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
の管理しているメモリ領域と
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ関数
Pokky.statusDataDisplay()
の管理しているメモリ領域
が
🌞生成されていることになるんです🌞
そして
bの子クラスDragon&型の参照変数宣言
Dragon& b=Pokky;
を実行して
子クラスDragon&型の参照変数
b
を作製します
子クラスDragon&型の参照変数
b
に
子クラスDragon型のオブジェクトPokkyを
Dragon& b=Pokky;
と代入します
この場合
子クラスDragon&型の参照変数bにドット演算子.を用いた
b.name
b.HP
b.MP
b.statusDataDisplay()
は
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ変数
Pokky.name
Pokky.HP
Pokky.MP
子クラスDragon型のオブジェクトPokkyの(子クラスにもともと備わっている)メンバ関数
Pokky.statusDataDisplay()
と
同じ働きをすることになります」
マックス「
子クラスDragon型のオブジェクトPokkyの
Pokky.statusDataDisplay()
と同じ働きをする・・・か
オーバーライドがおこなわれているのか?」
ソーラー「そうなんです
子クラスDragon&型の参照変数bに
子クラスDragon型のオブジェクトPokkyが代入された場合
オーバライドの働きにより
子クラスDragon&型の参照変数bにドット演算子.を用いた
b.statusDataDisplay()
は
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域でなく
子クラスDragon型のオブジェクトPokkyの(子クラスにもともと備わっている)メンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
にアクセスすることになります
子クラスDragon&型の参照変数bに
子クラスDragon型のオブジェクトPokkyを
代入したので
子クラスDragon&型の参照変数bにドット演算子.を用いた
b.name
b.HP
b.MP
b.statusDataDisplay()
は
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ変数
Pokky.name
Pokky.HP
Pokky.MP
が管理しているメモリ領域
と
子クラスDragon型のオブジェクトPokkyの(子クラスにもともと備わっている)メンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
にアクセスすることになったわけです
そして今回 新たに登場するパターンです
Pokkyの子クラスDragon型のオブジェクト宣言
Dragon Pokky;
の実行によって子クラスDragon型のオブジェクトPokkyが作製された場合
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ変数
Pokky.name
Pokky.HP
Pokky.MP
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
さらに
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ変数
Pokky.DP
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ関数
Pokky.statusDataDisplay()
が生成されることになります
🌞同じ名前の🌞
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
と
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ関数
Pokky.statusDataDisplay()
が
生成されているところが
🌞ポイントです🌞
このとき
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ変数
Pokky.name
Pokky.HP
Pokky.MP
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
と
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ変数
Pokky.DP
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ関数)
Pokky.statusDataDisplay()
が管理しているメモリ領域
が存在していることになります
🌞同じ名前だけど2つの異なる🌞
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
の管理しているメモリ領域と
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ関数
Pokky.statusDataDisplay()
の管理しているメモリ領域
が
🌞生成されていることになるんです🌞
このとき
aの子クラスDragon&型の参照変数宣言
Dragon& a=Pokky;
を実行して
子クラスDragon&型の参照変数
a
を生成するのでなく
aの親クラスGameCharacter&型の参照変数宣言
GameCharacter& a=Pokky;
を実行して
親クラスGameCharacter&型の参照変数
a
を作製します
そして
親クラスGameCharacter&型の参照変数
a
に
子クラスDragon型のオブジェクトPokkyのアドレス&Pokkyを
a=&Pokky;
と代入します
この場合
親クラスGameCharacter&型の参照変数aにドット演算子.を用いた
a.name
a.HP
a.MP
a.statusDataDisplay()
は
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ変数
Pokky.name
Pokky.HP
Pokky.MP
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
と
同じ働きをすることになります」
マックス「なんで なんかさっきとちがってないか?
a.statusDataDisplay()
は
子クラスDragon型のオブジェクトPokkyの(親クラスに備わっている、親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
と同じはたらきをすることになるのか?
オーバーライドはおこなわれないのか?」
ソーラー「それもそのはずなんです
Pokkyの子クラスDragon型のオブジェクト宣言
Dragon Pokky;
を実行し
🌞親クラスGameCharacter&型の参照変数aに🌞
子クラスDragon型のオブジェクトPokkyを代入する
GameCharacter& a=Pokky;
を実行した場合
親クラスGameCharacter&型の参照変数aにドット演算子.を用いた
a.name
a.HP
a.MP
a.statusDataDisplay()
は
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ変数
Pokky.name
Pokky.HP
Pokky.MP
子クラスDragon型のオブジェクトPokkyの(|親クラスに備わっている、親クラスから引き継いだ《🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞》)メンバ関数
Pokky.statusDataDisplay()
の管理しているメモリ領域にしかアクセスできないからなんです
親クラスGameCharacterのメンバ関数
statusDataDisplay()
と同じ名前のメンバ関数を
子クラスDragonのメンバ関数
statusDataDisplay()
として
設定する
オーバライドがしてあってもしてなくても
根本的に
💖親クラスGameCharacter&型の参照変数a💖
にドット演算子.を用いた
a.statusDataDisplay()
では
子クラスDragon型のオブジェクトPokkyの(親クラスに備わっている、親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域にしかアクセスできません
子クラスDragon型のオブジェクトPokkyの(子クラスにもともと備わっている)メンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
にはアクセスできません
このように
💖親クラスGameCharacter&型の参照変数aに💖
🍋子クラスDragon型のオブジェクトPokkyを🍋
代入した場合
親クラスGameCharacter&型の参照変数aにドット演算子.を用いた
a.name
a.HP
a.MP
a.statusDataDisplay()
は
子クラスDragon型のオブジェクトPokkyの(親クラスに備わっている、親クラスから引き継いだ)メンバ変数
Pokky.name
Pokky.HP
Pokky.MP
が管理しているメモリ領域
と
子クラスDragon型のオブジェクトPokkyの(親クラスに備わっている、親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
にしかアクセスできない
子クラスDragon型のオブジェクトPokkyの(子クラスに備わっている)メンバ変数
Pokky.DP
が管理しているメモリ領域
と
子クラスDragon型のオブジェクトPokkyの(子クラスに備わっている)メンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
にはアクセスできない
というのは
💖親クラスGameCharacter&型の参照変数aに💖
🍋子クラスDragon型のオブジェクトPokkyを🍋
代入したことが
原因なんです
なぜなら
このエピソードの初めのほうでも述べられたように
親クラスGameCharacter型のオブジェクトPokkyのメンバ変数
Pokky.name
Pokky.HP
Pokky.MP
が管理しているメモリ領域と
親クラスGameCharacter型のオブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
は
あるメモリ領域を占有していますが
それらのメモリをまとめて
ある変数が管理しているととらえると
その変数を格納する
その(変数の型)&型の参照変数も
登場してくることになります
同様に
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ変数
Pokky.name
Pokky.HP
Pokky.MP
が管理しているメモリ領域と
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
も
あるメモリ領域を占有していますが
それらのメモリをまとめて
ある変数が管理しているととらえると
その変数を格納する
その(変数の型)&の参照変数も
登場してくることになるのですが
それらのメモリを代表するアドレスを格納しているのが
ともに
親クラスGameCharacter&型の参照変数aになっているというわけです
子クラスDragon型のオブジェクトPokkyは
🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ変数
Pokky.name
Pokky.HP
Pokky.MP
が管理しているメモリ領域と
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞
に加えて
💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ変数
Pokky.DP
が管理しているメモリ領域と
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖
を管理しているわけですが
🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ変数
Pokky.name
Pokky.HP
Pokky.MP
が管理しているメモリ領域と
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞
だけにアクセスできるのが
親クラスGameCharacter&型の参照変数aなんだね
子クラスDragon&型の参照変数aがアクセスできるのは
🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ変数
Pokky.name
Pokky.HP
Pokky.MP
が管理しているメモリ領域と
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞
に加えて
💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ変数
Pokky.DP
が管理しているメモリ領域と
子クラスDragon型のオブジェクトPokkyの(子クラスに元から備わっている)メンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖
の両方というわけなんだよ
親クラスGameCharacter&型の参照変数aがアクセスできるのは
🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ変数
Pokky.name
Pokky.HP
Pokky.MP
が管理しているメモリ領域と
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞
だけなので
親クラスGameCharacter&型の参照変数aに
ドット演算子.が用いられた
Pokky.statusDataDisplay();
が実行されると
子クラスDragon型のオブジェクトPokkyの(親クラスから引き継いだ)メンバ関数
Pokky.statusDataDisplay();
に相当するものが実行されることになるんだよ
だから
Pokky.statusDataDisplay();
が実行されても
子クラスDragon型のオブジェクトPokkyの(オーバーライドしている子クラスに元から備わっている)メンバ関数
Pokky.statusDataDisplay();
に相当するものが実行されることはないんだ
オーバーライドが機能しないというわけだね
」
マックス「おうぅ
いい説明じゃないか
マックス「オーバーライドが機能しない
親クラスGameCharacter&型の参照変数aにドット演算子.を用いた
a.statusDataDisplay()
では
子クラスDragon型のオブジェクトPokkyの(子クラスに備わっている)メンバ関数
Pokky.statusDataDisplay()
が管理しているメモリ領域
にはアクセスできないか・・・
💖親クラスGameCharacter&型の参照変数aに💖
🍋子クラスDragon型のオブジェクトを🍋
代入して
親クラスGameCharacter&型の参照変数aをつかうときの宿命というやつか・・・」
ソーラー「そうですね
ここまでで十分なかんじなんだけど
なんとかして
もっと簡単に
ちょっと別の感じの説明をおこなってみると
親クラスGameCharacter&型の参照変数
a
に
🍋子クラスDragon型🍋のオブジェクトPokky
が代入された状態では
a.name = "ポッキー";
a.HP = 15;
a.MP = 5;
🌞a.statusDataDisplay();🌞
が実行されるとき
あたかも
aには
🍋子クラスDragon型🍋のオブジェクトPokky
が代入されているにもかかわらず
親クラスGam
親クラスGameCharact
が代入されているととらえれば
わかりやすいかな?」
マックス「
🍋子クラスDragon型🍋のオブジェクトPokky
が代入されているのではなく
親クラスGameCharacter&型の参照変数aに
親クラスGameCharacter型のオブジェクトPokky
が代入されていることになるんかい
実際には
子クラスDragon型のオブジェクトPokky
Pokky
が代入されているんだが
そう考えることもできるというわけだ
☆親クラスGameCharacter&型☆の参照変数aに
☆親クラスGameCharacter型☆のオブジェクトPokky
か・・・
単純といえば単純か?」
ソーラー「そうなんです
親クラスGameCharacter型のオブジェクトPokkyを生成した場合の
親クラスGameCharacter型のオブジェクトPokky
と
子クラスGameCharacter型のオブジェクトPokkyを生成した場合の
子クラスDragon型のオブジェクトPokky
は
もちろん違う変数(異なるメモリを管理する変数)ですが
親クラスGameCharacter&型の参照変数
a
に
🍋子クラスDragon型🍋のオブジェクトPokky
が代入された状態を
💖親クラスGameCharacter型💖のオブジェクト
Pokky
が代入された状態ととらえると
わかりやすくなる
と思うんだ
ですので
親クラスGameCharacter&型の参照変数
a
に
💖親クラスGameCharacter型💖のオブジェクトPokky
Pokky
が代入された状態ととらえると
a.name
a.HP
a.MP
は
💖親クラスGameCharacter型💖のオブジェクトPokkyのメンバ変数
Pokky.name
Pokky.HP
Pokky.MP
に相当していると
とらえることができます
もちろん
a.statusDataDisplay()
は
💖親クラスGameCharacter型💖の
オブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay()
に相当するものととらえることができます
a.statusDataDisplay()
は
💖親クラスGameCharacter型💖の
オブジェクトPokkyのメンバ関数
Pokky.statusDataDisplay()
ととらえると
a.statusDataDisplay()が実行されると
何が実行されるか
がわかりやすくなります
その場合
a.statusDataDisplay();
が実行されたなら
親クラスGameCharacterのメンバ関数の定義
👇
void GameCharacter::statusDataDisplay() {
cout << name << "\n";
cout << "HP " << HP << "\n";
cout << "MP " << MP << "\n";
cout << "親クラスのメンバ関数statusDataDisplay()が実行されました" << "\n";
}
の
name
HP
MP
に
Pokky.name
Pokky.HP
Pokky.MP
が代入されたものが実行されることになるので
コマンドプロンプト画面に
ポッキー
HP 15
MP 5
親クラスのメンバ関数statusDataDisplay()が実行されました
が表示されることがわかりますね
つまり
💖親クラスGameCharacter&型💖の参照変数宣言
GameCharacter& a;
によって作製された
親クラスGameCharacter&型の参照変数
a
に
Pokkyの子クラスDragon型のオブジェクト宣言
Dragon Pokky;
により生成される
🍋子クラスDragon型🍋のオブジェクトPokky
を
GameCharacter& a=Pokky;
(参照変数宣言は参照変数宣言と同時に初期化される必要があります)
と
代入するということを
単純に
Pokkyの親クラスGameCharacter型のオブジェクト宣言
GameCharacter Pokky;
が実行されて
生成される
親クラスGameCharacter型のオブジェクトPokky
が
親クラスGameCharacter&型の参照変数
a
に
代入されると
とらえたというわけです
正しくはないんだけど
このように理解しても
そんなに問題はないんだ😊」
マックス「おお うまい方法をおもいついたな」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます