🌻天国にいけるC++言語入門🌻 進化し続けるオブジェクト指向プログラミング ver3.2307
新たに子クラスを作製しプログラム内の関数を親クラスの仮想関数をオーバーライドした子クラスのメンバ関数の定義に設定すれば子クラス型のオブジェクトのメンバ関数を実行してその関数を実行することができます
プログラム内の関数を親クラスのメンバ関数をオーバーライドした子クラスのメンバ関数の定義に設定してみましょう
新たに子クラスを作製しプログラム内の関数を親クラスの仮想関数をオーバーライドした子クラスのメンバ関数の定義に設定すれば子クラス型のオブジェクトのメンバ関数を実行してその関数を実行することができます
ソーラー「
プログラム内にある関数があるとします
新たに子クラスを作製し
親クラスの純粋仮想関数(仮想関数)をオーバーライドした
子クラスのメンバ関数の定義にその関数を設定すれば
子クラス型のオブジェクトを生成して
子クラス型のオブジェクトのメンバ関数を実行することにより
その関数を
実行することができるようになります」
マックス「
親クラス*型のポインタ変数に子クラス型のオブジェクトのアドレスを代入したり
親クラス&型の参照変数に子クラス型のオブジェクトを代入したり
はしないのか
子クラス型のオブジェクトを生成して
子クラス型のオブジェクトの(オーバーライドしている)メンバ関数を実行するだけ・・・
??単に
親クラスの純粋仮想関数(仮想関数)を
オーバーライドした子クラスのメンバ関数の定義が用いられたものが
実行されるということか(´▽`*)
ポリモーフィズム(多態性)は関係ないってわけだ
簡単じゃないか」
solarplexusss「??」
ソーラー「そうなんです
原理はとても簡単です
具体例をみていこうよ」
ソーラー「まず一つの親クラスと
その親クラスのメンバ変数宣言、メンバ関数宣言を
継承した
子クラスを
3つ用意します
まずは
親クラスCharacterのクラス宣言と
親クラスCharacterのメンバ関数characterdisplay()
の定義を
👇
____________________________________
class Character{
public:
virtual void characterdisplay()=0;
};
//🌞virtual void characterdisplay()は純粋仮想関数なので定義を記述していません
____________________________________
とします
親クラスCharacterのメンバ関数characterdisplay()
は純粋仮想関数に設定されています
純粋仮想関数が設定されているので親クラスCharacterは抽象クラスです
そして
1つ目の
子クラスである
CircleCharacterのクラス宣言と
子クラスCircleCharacterのメンバ関数
characterdisplay()
の定義を
👇
_____________________________________________________________________
class CircleCharacter:public Character
{
public:
void characterdisplay();//🌞親クラスCharacterのメンバ変数characterdisplay()をオーバーライドしています
};
void CircleCharacter::characterdisplay(){
cout << "〇" ;
}
____________________________________
とします。」
マックス「子クラスCircleCharacter(〇文字クラス)は
〇
を
コマンドプロンプト画面に表示する機能を持っているクラスというわけか」
ソーラー「子クラスCircleCharacter型のオブジェクト宣言
CircleCharacter circle1;
を実行し
生成される
💖子クラス💖CircleCharacter型のオブジェクトcircle1のメンバ関数
circle1 characterdisplay();
を実行すると
オーバーライドの働きにより
親クラスCharacterのメンバ関数
characterdisplay()
の定義のかわりに
子クラスCircleCharacterのメンバ関数
characterdisplay()
の定義
void CircleCharacter::characterdisplay(){
cout << "〇" ;
}
が用いられたものが実行されることになります
cout << "〇" ;
が実行されるので
〇がコマンドプロンプト画面に表示されます。」
次に
2つ目の
子クラスである
StarCharacterのクラス宣言と
子クラスStarCharacterのメンバ関数
characterdisplay()
の定義を
👇
_____________________________________________________________________
class StarCharacter:public Character
{
public:
void characterdisplay();//🌞親クラスCharacterのメンバ変数characterdisplay()をオーバーライドしています
};
void StarCharacter::characterdisplay(){
cout << "☆" ;
}
____________________________________
とします。」
マックス「子クラスStarCharacter(☆文字クラス)は
☆
をコマンドプロンプト画面に表示する機能を持っているクラスというわけか」
ソーラー「子クラスStarCharacter型のオブジェクト宣言
StarCharacter star1;
を実行し
生成される
💖子クラス💖StarCharacter型のオブジェクトstar1のメンバ関数
star1 characterdisplay();
を実行すると
オーバーライドの働きにより
親クラスCharacterのメンバ関数
void characterdisplay()
の定義のかわりに
子クラスStarCharacterのメンバ関数
characterdisplay()
の定義が
用いられたものが実行されることになります
子クラスStarCharacterのメンバ関数
characterdisplay()
の定義
void StarCharacter::characterdisplay(){
cout << "☆" ;
}
が用いられたものが実行されることになります
cout << "☆" ;
が実行されるので
☆がコマンドプロンプト画面に表示されます。」
ソーラー「
3つ目の
子クラスである
SquareCharacterのクラス宣言と
子クラスSquareCharacterのメンバ関数
void characterdisplay()
の定義を
👇
_____________________________________________________________________
class SquareCharacter:public Character
{
public:
void characterdisplay();//🌞親クラスCharacterのメンバ変数characterdisplay()をオーバーライドしています
};
void SquareCharacter::characterdisplay(){
cout << "□" ;
}
____________________________________
とします。」
マックス「子クラスSquareCharacter(□クラス)は
□
をコマンドプロンプト画面に表示する機能を持っているクラスというわけか」
ソーラー「子クラスSquareCharacter型のオブジェクト宣言
SquareCharacter square1;
を実行し
生成される
💖子クラス💖SquareCharacter型のオブジェクトsquare1のメンバ関数
square1 characterdisplay();
を実行すると
オーバーライドの働きにより
親クラスCharacterのメンバ関数
characterdisplay()
の定義のかわりに
子クラスSquareCharacterのメンバ関数
characterdisplay()
の定義が用いられたものが実行されることになります
子クラスSquareCharacterのメンバ関数の定義は
👇
void SquareCharacter::characterdisplay(){
cout << "□" ;
}
👆
なので
cout << "□" ;
が実行され
□がコマンドプロンプト画面に表示されます。」
ソーラー「これらのクラスを用いて
まず
〇
☆
□
をコマンドプロンプト画面に表示してみます
そのプログラムはこちらとなります。
👇
#include <iostream>
using namespace std;
class Character {
public:
virtual void characterdisplay()= 0;
};
//🌞virtual void characterdisplay()は純粋仮想関数なので定義を記述していません
class CircleCharacter:public Character
{
public:
void characterdisplay();//🌞親クラスCharacterのメンバ変数characterdisplay()をオーバーライドしています
};
void CircleCharacter::characterdisplay() {
cout << "〇";
}
class StarCharacter :public Character
{
public:
void characterdisplay();//🌞親クラスCharacterのメンバ変数characterdisplay()をオーバーライドしています
};
void StarCharacter::characterdisplay() {
cout << "☆";
}
class SquareCharacter:public Character
{
public:
void characterdisplay();//🌞親クラスCharacterのメンバ変数characterdisplay()をオーバーライドしています
};
void SquareCharacter::characterdisplay() {
cout << "□";
}
int main() {
CircleCharacter circle;
StarCharacter star;
SquareCharacter square;
circle.characterdisplay();
cout << "\n";//👈🌞ここに注目!
star.characterdisplay();
cout << "\n";//👈🌞ここに注目!
square.characterdisplay();
cout << "\n";//👈🌞ここに注目!
return 0;
}
プログラムの実行結果
〇
☆
□
ソーラー「さて
ここで
新たに
親クラスCharacterを継承した
子クラスChangelineCharacterを作製します
そのときの
子クラスChangelineCharacterのクラス宣言とそのメンバ関数characterdisplay()の定義を
以下のように設定してみます
👇
class ChangelineCharacter:public Character
{
public:
void characterdisplay();//🌞親クラスCharacterのメンバ関数characterdisplay()をオーバーライドしています
};
void ChangelineCharacter::characterdisplay() {
cout << "\n";
}
つまり
子クラスChangelineCharacter
とは
🌞cout << "\n";🌞
を実行するためのクラスなんです」
マックス「ど~いうことおんん」
ソーラー「
このように子クラスChangelineCharacterが設定された状態で
子クラスChangelineCharacter型のオブジェクト宣言
ChangelineCharacter changeline;
を実行し
子クラスChangelineCharacter型のオブジェクトchangelineのメンバ関数
changeline.characterdisplay();
を実行したとき
親クラスChangelineCharacterのメンバ関数
characterdisplay()
を
オーバーライドした
子クラスChangelineCharacterのメンバ関数characterdisplay()が実行されることになります
つまり
子クラスChangelineCharacterのメンバ関数characterdisplay()の定義
👇
void ChangelineCharacter::characterdisplay() {
cout << "\n";
}
👆
の
cout << "\n";
が実行されることになります
となると
先程のプログラムは
changeline.characterdisplay();
を用いて
次のように書き換えることができます
👇
#include <iostream>
using namespace std;
class Character {
public:
virtual void characterdisplay() = 0;
};
//🌞virtual void characterdisplay()は純粋仮想関数なので定義を記述していません
class CircleCharacter :public Character
{
public:
void characterdisplay();//🌞親クラスGameCharacterのメンバ変数characterdisplay()をオーバーライドしています
};
void CircleCharacter::characterdisplay() {
cout << "〇";
}
class StarCharacter :public Character
{
public:
void characterdisplay();//🌞親クラスGameCharacterのメンバ変数characterdisplay()をオーバーライドしています
};
void StarCharacter::characterdisplay() {
cout << "☆";
}
class SquareCharacter :public Character
{
public:
void characterdisplay();//🌞親クラスGameCharacterのメンバ変数characterdisplay()をオーバーライドしています
};
void SquareCharacter::characterdisplay() {
cout << "□";
}
class ChangelineCharacter :public Character
{
public:
void characterdisplay();//🌞親クラスGameCharacterのメンバ変数characterdisplay()をオーバーライドしています
};
void ChangelineCharacter::characterdisplay() {
cout << "\n";
}
int main() {
CircleCharacter circle;
StarCharacter star;
SquareCharacter square;
ChangelineCharacter changeline;
circle.characterdisplay();
changeline.characterdisplay();//👈🌞ここに注目!
star.characterdisplay();
changeline.characterdisplay();//👈🌞ここに注目!
square.characterdisplay();
changeline.characterdisplay();//👈🌞ここに注目!
return 0;
}
プログラムの実行結果
〇
☆
□
ソーラー「このように
プログラム内の関数
🍓cout << "\n";🍓
は
子クラスChangecharacter型のオブジェクトchangeline
と
親クラスCircleの純粋仮想関数をオーバーライドした
子クラスのメンバ関数characterdisplay()
を用いた
changeline.characterdisplay();
を用いて
実行することができるというわけです
cout << "\n";
を
親クラスCircleの純粋仮想関数characterdisplay()をオーバーライドした
子クラスChangecharacterのメンバ変数characterdisplay()
の定義に用いたところがポイントです」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます