親クラスのクラス宣言内でアクセス指定子がpublicに設定された親クラスのメンバ変数、メンバ関数をアクセス指定子privateを使って子クラスへ継承してみます

ソーラー「今度は


親クラスGameCharacterのメンバ変数宣言


string name;

int HP;

int MP;



親クラスGameCharacterのメンバ関数宣言


void statusDataDisplay();


のアクセス指定子はpublicのまま



class Dragon:private GameCharacter


のように


アクセス指定子


private


を用いて


親クラスGameCharacterから


子クラスDragonへ


クラスの継承を行ってみたいと思います




class Dragon:private GameCharacter


のように


アクセス指定子privateを用いて継承が行われた状態で


まずは


main関数内で


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


GameCharacter Lyliane;


だけを実行してみたいと思います。


ポイントは


親クラスGameCharacter


というところです。


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


GameCharacter Lyliane;


を実行した場合


関係してくるのは


親クラスGameCharacter


のみで


子クラスDragon

は関係してきません。


そのプログラムはこっちだね。」

👇

#include <iostream>

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

using namespace std;


//👇🌞🌞🌞クラスGameCharacterです🌞🌞🌞

class GameCharacter {


public:

string name;

int HP;

int MP;


void statusDataDisplay();


//クラスGameCharacterにはuseFireRecovery(GameCharacter& a)を設定しません

};



void GameCharacter::statusDataDisplay() {


cout << name << "\n";

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

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

}





//👇🌞🌞🌞クラスGameCharacterを継承した子クラスDragonのクラス宣言です🌞🌞🌞


class Dragon:private GameCharacter {

public:

void useFireRecovery(GameCharacter& a);


};



void Dragon::useFireRecovery(GameCharacter& a) {

cout << name << "は灼熱のフレアを" << a.name << "に吐いた !" << "\n";

cout << a.name << "は灼熱のフレアを受け燃え上がった!" << "\n";


a.HP += 10;


cout << a.name << "の体力は10回復した" << "\n";


}


int main() {


GameCharacter Lyliane;


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

Lyliane.HP = 10;

Lyliane.MP = 8;


Lyliane.statusDataDisplay();

return 0;

}



プログラムの実行結果


リリアーネ

HP 10

MP 8



マックス「main関数内で


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


GameCharacter Lyliane;


を実行すると


ふっつうに


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


Lyliane.name

Lyliane.HP

Lyliane.MP



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


Lyliane.statusDataDisplay()


が生成されて


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

Lyliane.HP = 10;

Lyliane.MP = 8;


Lyliane.statusDataDisplay();

のように


使用することができているというわけだ。」


てんC「このとき


子クラスDragonは


プログラムに関係してきませんね」


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


このプログラムでは


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


Dragon Pokky;


は実行されず


親クラスGameCharacterから継承した


メンバ変数宣言


string name;

int HP;

int MP;


メンバ関数宣言


void statusDataDisplay();


を用いた


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


Pokky.name

Pokky.HP

Pokky.MP


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


Pokky.statusDataDisplay()


は使用されていません



このプログラムでは


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


GameCharacter Lyliane;


によって生成された


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


Lyliane.name

Lyliane.HP

Lyliane.MP


"リリアーネ"

10

8



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

Lyliane.HP = 10;

Lyliane.MP = 8;


と代入されています


そして


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


Lyliane.statusDataDisplay();


が実行されて


プログラムの実行結果


リリアーネ

HP 10

MP 8


が表示されています。」


マックス「う~ん  普通だなぁ」


ソーラー「今度は


親クラスGameCharacterのメンバ変数宣言


string name;

int HP;

int MP;



親クラスGameCharacterのメンバ関数宣言


void statusDataDisplay();


のアクセス指定子はpublicのまま



class Dragon:private GameCharacter


のように


アクセス指定子


private


を用いて


親クラスGameCharacterから


子クラスDragonへ


クラスの継承が行われた状態で



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


Dragon Pokky;



実行してみます。


そのプログラムはこちらとなります。」


👇


#include <iostream>

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

using namespace std;


//👇🌞🌞🌞クラスGameCharacterです🌞🌞🌞

class GameCharacter {


public:

string name;

int HP;

int MP;


void statusDataDisplay();


//クラスGameCharacterにはuseFireRecovery(GameCharacter& a)を設定しません

};



void GameCharacter::statusDataDisplay() {


cout << name << "\n";

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

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

}





//👇🌞🌞🌞クラスGameCharacterを継承したクラスDragonです🌞🌞🌞

//👇🌞🌞🌞アクセス指定子がpublicからprivateに変更されています🌞🌞🌞

class Dragon :private GameCharacter {

public:

void useFireRecovery(GameCharacter& a);


};



void Dragon::useFireRecovery(GameCharacter& a) {

cout << name << "は灼熱のフレアを" << a.name << "に吐いた !" << "\n";

cout << a.name << "は灼熱のフレアを受け燃え上がった!" << "\n";


a.HP += 10;


cout << a.name << "の体力は10回復した" << "\n";


}


int main() {


Dragon Pokky;

Pokky.name = "ポッキー";

Pokky.HP = 15;

Pokky.MP = 5;



Pokky.statusDataDisplay();


return 0;

}


ビルド実行結果



エラー (アクティブ) E0265 関数 "GameCharacter::statusDataDisplay" (宣言された 行 19) にアクセスできません

エラー (アクティブ) E0265 メンバー "GameCharacter::name" (宣言された 行 9) にアクセスできません

エラー (アクティブ) E0265 メンバー "GameCharacter::MP" (宣言された 行 11) にアクセスできません

エラー (アクティブ) E0265 メンバー "GameCharacter::HP" (宣言された 行 10) にアクセスできません

エラー C2247 'GameCharacter::statusDataDisplay' はアクセスできません。'Dragon' は 'private' で 'GameCharacter' からの継承で使われています。

エラー C2247 'GameCharacter::name' はアクセスできません。'Dragon' は 'private' で 'GameCharacter' からの継承で使われています。

エラー C2247 'GameCharacter::MP' はアクセスできません。'Dragon' は 'private' で 'GameCharacter' からの継承で使われています。

エラー C2247 'GameCharacter::HP' はアクセスできません。'Dragon' は 'private' で 'GameCharacter' からの継承で使われています。



マックス「なんだ ビルドエラーが表示されたぞお~ん


なんで


まさか


親クラスGameCharacter


から


子クラスDragonへ


class Dragon:private GameCharacter



アクセス指定子privateを用いて


クラスの継承を実行したからか?」


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


このプログラムでは


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


Dragon Pokky;


の実行によって


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


Pokky.name

Pokky.HP

Pokky.MP


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


Pokky.statusDataDisplay()


を作製しようとしています。」


マックス「ここまではアクセス指定子publicを用いて


クラスの継承行った場合と同じ展開とおなじというわけか」


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




class Dragon:private GameCharacterのように


アクセス指定子privateを用いて


親クラスGameCharacter


から


子クラスDragonへ


継承を行った場合は


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


メンバ変数宣言


string name;

int HP;

int MP;


メンバ関数宣言

void statusDataDisplay();



子クラスDragonのクラス宣言内に引き継がれているんです」


マックス「はい? 聞き間違えか?


子クラスDragonのクラス宣言内に引き継がれていない


が正解なんだろう?」


ソーラー「いいえぇ


class Dragon:private GameCharacterのように


アクセス指定子privateを用いて


親クラスGameCharacter


から


子クラスDragonへ


継承を行った場合は


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


メンバ変数宣言


string name;

int HP;

int MP;


メンバ関数宣言

void statusDataDisplay();



  🌞子クラスDragonのクラス宣言内に引き継がれているんです🌞」



マックス「な、なんだ?


🌞子クラスDragonのクラス宣言内に引き継がれている🌞


のなら


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


Dragon Pokky;


の実行によって


子クラスDragon型のオブジェクトPokkyを作製したとき


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


Pokky.name

Pokky.HP

Pokky.MP


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


Pokky.statusDataDisplay()


も生成されるんじゃないのか?


だから


Dragon Pokky;


の実行の後


Pokky.name = "ポッキー";

Pokky.HP = 15;

Pokky.MP = 5;



Pokky.statusDataDisplay();


は実行できるので


ビルドエラーが表示されることにはならないはずだが・・・」


ソーラー「


子クラスDragon型のオブジェクトPokkyを作製したとき


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


Pokky.name

Pokky.HP

Pokky.MP


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


Pokky.statusDataDisplay()


が生成されるのを


防いでいるのが


親クラスGameCharacter


から


子クラスDragonへ



class Dragon:private GameCharacterのように


継承したときの


アクセス指定子privateなんです


このアクセス指定子privateの働きにより


main関数内で


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


Dragon Pokky;


を実行しても



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


Pokky.name

Pokky.HP

Pokky.MP


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


Pokky.statusDataDisplay()


は生成されず



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


Pokky.name

Pokky.HP

Pokky.MP


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


Pokky.statusDataDisplay()


を使用しようとすると


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


マックス「もしや・・・



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


メンバ変数宣言


string name;

int HP;

int MP;


メンバ関数宣言

void statusDataDisplay();


のアクセス指定子はpublicだったのが


class Dragon:private GameCharacterのように


アクセス指定子privateを用いて


親クラスGameCharacter


から


子クラスDragonへ


継承を行った場合は


親クラスGameCharacterの


メンバ変数宣言

public:

string name;

int HP;

int MP;


メンバ関数宣言


public:

void statusDataDisplay();



親クラスGameCharacterの


メンバ変数宣言

public:

string name;

int HP;

int MP;


メンバ関数宣言


public:

void statusDataDisplay();


のアクセス指定子がpublicからprivateに


以下のように書き換えられた状態

👇

private:

string name;

int HP;

int MP;


メンバ関数宣言


private:

void statusDataDisplay();

👆


子クラスDragonのクラス宣言内に引き継がれているんじゃないか?」


ソーラー「おおっ 鋭い!


そうなんです


class Dragon:private GameCharacterのように


アクセス指定子privateを用いて


親クラスGameCharacter


から


子クラスDragonへ


継承を行った場合は


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


メンバ変数宣言


string name;

int HP;

int MP;


メンバ関数宣言

void statusDataDisplay();


のアクセス指定子はpublicからprivateに書き換えられて


子クラスDragonへ引き継がれています


つまり


子クラスDragonのクラス宣言には


以下のように


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


メンバ変数宣言


string name;

int HP;

int MP;


メンバ関数宣言

void statusDataDisplay();


は引きつがれることになります」


子クラスDragonのクラス宣言は以下のようになります

👇

class Dragon :private GameCharacter {


private:


string name;

int HP;

int MP;


void statusDataDisplay();



public:

void useFireRecovery(GameCharacter& a);


};




後でも詳しく述べられますが


アクセス指定子publicより


アクセス指定子privateは強い影響力をもっています



ですので


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


メンバ変数宣言


string name;

int HP;

int MP;


メンバ関数宣言

void statusDataDisplay();


のアクセス指定子は


publicからprivateに書き換えられたんだよ」




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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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