🌻天国にいけるC++言語入門🌻 進化し続けるオブジェクト指向プログラミング ver3.2307
通常の自作関数と違い オブジェクトのメンバ関数を実行することにより オブジェクトのメンバ変数、静的メンバ変数に格納される値を 変更することができます。
通常の自作関数と違い オブジェクトのメンバ関数を実行することにより オブジェクトのメンバ変数、静的メンバ変数に格納される値を 変更することができます。
ソーラー「さあて
このエピソードのタイトルは
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
通常の自作関数と違い オブジェクトのメンバ関数を実行することにより オブジェクトのメンバ変数、静的メンバ変数に格納される値を 変更することができます。
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
となっていますが
正式には
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
通常、自作関数が実行されたとき
自作関数内で変数宣言された変数は
格納されたデータとともに消去されますが
オブジェクトのメンバ関数を実行した場合は
オブジェクトのメンバ変数、オブジェクトの静的メンバ変数は
消去されず
オブジェクトのメンバ変数、オブジェクトの静的メンバ変数に
格納されたデータも消去されません
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
となっています。
マックス「なにぃ
いまさら そのネタをもってくるのか?
いままで
🌞さんざん
オブジェクトのメンバ関数を実行することにより
オブジェクトのメンバ変数、オブジェクトの静的メンバ変数に格納される値を
変更してきたじゃないか
その際
オブジェクトのメンバ変数、オブジェクトの静的メンバ変数は
格納されたデータとともに消去されなかっただろう
そもそも
オブジェクトのメンバ変数、オブジェクトの静的メンバ変数は
オブジェクトのメンバ関数内で定義された変数ではないんじゃないか?」
ソーラー「では・・・
すこしだけ
いいかえると
main関数内で
オブジェクトのメンバ関数が実行されて
オブジェクトのメンバ変数、静的メンバ変数に格納された値が
変更されたとしても
つまり
オブジェクトのメンバ関数の実行後も
オブジェクトのメンバ変数、静的メンバ変数は消去されることなく
オブジェクトのメンバ変数、静的メンバ変数に格納された
値は変更されたまま保存されることになります。
ということなんです。」
マックス「ほとんどかわっていない・・・
えぇ?
何をいまさら・・・
そんなの当たり前じゃないか~い」
solarplexuss「そういう仕組みじゃなかったっけ??」
ソーラー「そうなんです
このエピソードでは
その当たり前のことを確認してみようというわけです。
まずは次のプログラムをご覧ください」
#include <iostream>
using namespace std;
class Cube{
public:
int no;
public:
float tate;
public:
float yoko;
public:
float takasa;
public:
Cube();
/*🌞🌞🌞クラスCubeのコンストラクタCube() のメンバ関数宣言を行っています*/
public:
void display(); //自作関数display()のクラスCubeのメンバ関数宣言を行っています
public:
static int a;
/*🌞🌞🌞ここですよ~ん🌞🌞🌞
静的メンバ変数aのCubeのメンバ変数宣言を行っています*/
};
Cube::Cube() {
no = 0;
tate = 0.0;
yoko = 0.0;
takasa = 0.0;
cout << "生成されたオブジェクトのメンバ変数を初期化しました" << "\n";
}
/*👆🌞
クラスCubeのコンストラクタCube()の定義を行っています
🌞*/
void Cube::display() {
cout << a << "回目のオブジェクトcube1のメンバ関数cube1.display()を実行しました" << "\n";
a++;
cout <<"cube1.aの値は" << a << "になりました" << "\n";
no++;
cout << "立方体につけられたナンバーは" << no << "です" << "\n";
tate++;
cout << "立方体の縦の長さは" << tate << "です" << "\n";
yoko++;
cout << "立方体の横の長さは" << yoko << "です" << "\n";
takasa++;
cout << "立方体の高さの長さは" << takasa << "です" << "\n";
}
//👆クラスCubeのメンバ関数となっている自作関数display()の定義をおこなっています
int Cube::a = 1;
//👆🌞🌞🌞ここです🌞🌞🌞静的メンバ変数aの初期化を行っています
//👆🌞🌞🌞静的メンバ変数aの格納する値は1になります
int main() {
Cube cube1;
//👆cube1のクラスCube型のオブジェクト宣言をおこなっています
/*🌞このとき オブジェクトcube1のコンストラクタが自動的に実行されています*/
cout << "オブジェクトcube1の静的メンバ変数cube1.aに代入された数値データは" << cube1.a << "です" << "\n";
cube1.display();
return 0;
}
プログラムの実行結果
生成されたオブジェクトのメンバ変数を初期化しました
オブジェクトcube1の静的メンバ変数cube1.aに代入された数値データは1です
1回目のオブジェクトcube1のメンバ関数cube1.display()を実行しました
cube1.aの値は2になりました
立方体につけられたナンバーは1です
立方体の縦の長さは1です
立方体の横の長さは1です
立方体の高さの長さは1です
ソーラー「
新たに設定し直された
クラスCubeのメンバ関数display()の定義
void Cube::display() {
cout << a << "回目のオブジェクトcube1のメンバ関数cube1.display()を実行しました" << "\n";
a++;
cout <<"cube1.aの値は" << a << "になりました" << "\n";
no++;
cout << "立方体につけられたナンバーは" << no << "です" << "\n";
tate++;
cout << "立方体の縦の長さは" << tate << "です" << "\n";
yoko++;
cout << "立方体の横の長さは" << yoko << "です" << "\n";
takasa++;
cout << "立方体の高さの長さは" << takasa << "です" << "\n";
}
では
a++;
no++;
tate++;
yoko++;
takasa++;
が用いられています。
a++;
は
a=a+1;
を表す命令文ですね。
このプログラムで
cube1のクラスCube型のオブジェクト宣言
Cube cube1;
の実行後
クラスCube型のオブジェクトcube1のコンストラクタが実行されます
つまり
クラスCubeのコンストラクタの定義
Cube::Cube() {
no = 0;
tate = 0.0;
yoko = 0.0;
takasa = 0.0;
cout << "生成されたオブジェクトのメンバ変数を初期化しました" << "\n";
}
の
no
tate
yoko
takasa
に
cube1.no
cube1.tate
cube1.yoko
cube1.takasa
が代入されて
cube1.no=0;
cube1.tate=0.0;
cube1.yoko=0.0;
cube1.takasa=0.0;
が実行されるので
クラスCube型のオブジェクトcube1のメンバ変数
cube1.no
cube1.tate
cube1.yoko
cube1.takasa
は
0
0.0
0.0
0.0
に
初期化されます
そして
クラスCube型のオブジェクトcube1のメンバ関数
cube1.display();
が実行されると
cube1のクラスCube型のオブジェクト宣言
Cube cube1;
によって作製された
クラスCube型のオブジェクトcube1の静的メンバ変数
cube1.a
クラスCube型のオブジェクトcube1のメンバ変数
cube1.no
cube1.tate
cube1.yoko
cube1.takasa
が
クラスCubeのメンバ関数であるdisplay()の定義
👇
void Cube::display() {
cout << a << "回目のオブジェクトcube1のメンバ関数cube1.display()を実行しました" << "\n";
a++;
cout <<"cube1.aの値は" << a << "になりました" << "\n";
no++;
cout << "立方体につけられたナンバーは" << no << "です" << "\n";
tate++;
cout << "立方体の縦の長さは" << tate << "です" << "\n";
yoko++;
cout << "立方体の横の長さは" << yoko << "です" << "\n";
takasa++;
cout << "立方体の高さの長さは" << takasa << "です" << "\n";
}
の
a
no
tate
yoko
takasa
に代入された
cout <<cube1.a<< "回目のオブジェクトcube1のメンバ関数cube1.display()を実行しました"<< "\n";
(cube1.a)++;
cout <<"cube1.aの値は" <<cube1.a<< "になりました" << "\n";
(cube1.no)++;
cout << "立方体につけられたナンバーは" << cube1.no << "です" << "\n";
(cube1.tate)++;
cout << "立方体の縦の長さは" << cube1.tate << "です" << "\n";
(cube1.yoko)++;
cout << "立方体の横の長さは" << cube1.yoko << "です" << "\n";
(cube1.takasa)++;
cout << "立方体の高さの長さは" << cube1.takasa << "です" << "\n";
が実行されることになります
このとき
Cubeのクラス宣言内の
aの静的メンバ変数宣言
static int a;
と
aのメンバ変数宣言
int Cube::a = 1;
が実行されていることにより
どのようなオブジェクト宣言
例えば
Cube cube1;
Cube cube2;
Cube ray;
のいずれか
が実行されても
生成される
クラスCube型のオブジェクトのメンバ変数
cube1.a
cube2.a
ray.a
は1の値をもつことになります。
たとえば
cube1のクラスCube型のオブジェクト宣言が行われたなら
生成されるそのクラスCube型のオブジェクトcube1のメンバ変数
cube1.aは1の値をもつことになります。
cube2のクラスCube型のオブジェクト宣言が行われたなら
生成されるそのクラスCube型のオブジェクトcube2のメンバ変数
cube2.aは1の値をもつことになります。
ray.aのクラスCube型のオブジェクト宣言が行われたなら
生成されるそのクラスCube型のオブジェクトrayのメンバ変数
ray.aは1の値をもつことになるというわけです。
(ただし ここでは
Cube cube1;
Cube cube2;
Cube ray;
のいずれかが実行されるとします)
ここでは
cube1のオブジェクト宣言が行われているので
生成されるオブジェクトの静的メンバ変数
cube1.a
は1の値をもつことになります。
ですので
cout <<cube1.a<< "回目のオブジェクトcube1のメンバ関数cube1.display()を実行しました" << "\n";
のビルド実行結果は
1回目のオブジェクトcube1のメンバ関数cube1.display()を実行しました
となります。
次に
(cube1.a)++;
は
cube1.a=cube1.a+1;
をあらわしていますね。
cube1.aは1の値に初期化されていたので
cube1.a=cube1.a+1;
が実行されると
cube1.aが今持っている値1に1を足したものが
cube1.aに代入されることになります
ですので
cube1.aは2の値をもつことになります。
となると
cout <<"cube1.aの値は" << cube1.a << "になりました" << "\n";
のビルド実行結果は
cube1.aの値は2になりました
が表示されることになります。
cube1.aの格納する値は2になりました
か・・・ふふっ😊
同様に
cout <<cube1.a<< "回目のオブジェクトcube1のメンバ関数cube1.display()を実行しました"<< "\n";
(cube1.a)++;
cout <<"cube1.aの値は" <<cube1.a<< "になりました" << "\n";
の実行の後
(cube1.no)++;
cout << "立方体につけられたナンバーは" << cube1.no << "です" << "\n";
(cube1.tate)++;
cout << "立方体の縦の長さは" << cube1.tate << "です" << "\n";
(cube1.yoko)++;
cout << "立方体の横の長さは" << cube1.yoko << "です" << "\n";
(cube1.takasa)++;
の実行により
cube1.noの格納する値は1になり
cube1.tateの格納する値は1になり
cube1.yokoの格納する値は1になり
cube1.takasaの格納する値は1になり
ビルド実行結果
立方体につけられたナンバーは1です
立方体の縦の長さは1です
立方体の横の長さは1です
立方体の高さの長さは1です
が表示されることになります。
どうかな?(*´▽`*)」
マックス「う~ん ふつう・・・だな」
ソーラー「
そして
このプログラムの最大のポイントは
クラスCube型のオブジェクトcube1のメンバ関数cube1.display()の実行により
プログラムの実行結果
cube1.aの値は2になりました
立方体につけられたナンバーは1です
立方体の縦の長さは1です
立方体の横の長さは1です
立方体の高さの長さは1です
が表示されたということなんです」
マックス「それの何が最大のポイントなのかわからんな」
ソーラー「ところで
クラスCubeのメンバ関数display()
は自作関数でした。
クラスCube型のオブジェクトcube1のメンバ関数である
cube1.display()が実行されると
クラスCubeのメンバ関数であるdisplay()の定義
void Cube::display() {
cout << a << "回目のオブジェクトcube1のメンバ関数cube1.display()を実行しました" << "\n";
a++;
cout << "cube1.aの値は" << a << "になりました" << "\n";
no++;
cout << "立方体につけられたナンバーは" << no << "です" << "\n";
tate++;
cout << "立方体の縦の長さは" << tate << "です" << "\n";
yoko++;
cout << "立方体の横の長さは" << yoko << "です" << "\n";
takasa++;
cout << "立方体の高さの長さは" << takasa << "です" << "\n";
}
の
a
no
tate
yoko
takasa
に
cube1.a
cube1.no
cube1.tate
cube1.yoko
cube1.takasa
が
代入された
cout <<cube1.a<< "回目のオブジェクトcube1のメンバ関数cube1.display()を実行しました"<< "\n";
(cube1.a)++;
cout <<"cube1.aの値は" <<cube1.a<< "になりました" << "\n";
(cube1.no)++;
cout << "立方体につけられたナンバーは" << cube1.no << "です" << "\n";
(cube1.tate)++;
cout << "立方体の縦の長さは" << cube1.tate << "です" << "\n";
(cube1.yoko)++;
cout << "立方体の横の長さは" << cube1.yoko << "です" << "\n";
(cube1.takasa)++;
cout << "立方体の高さの長さは" << cube1.takasa << "です" << "\n";
が実行されることになります
が
クラスCubeのメンバ関数display()は自作関数なので
クラスCube型のオブジェクトcube1のメンバ関数cube1.display()が実行されて
プログラムの実行結果
cube1.aの値は2になりました
立方体につけられたナンバーは1です
立方体の縦の長さは1です
立方体の横の長さは1です
立方体の高さの長さは1です
になったとしても
本当は
cube1.aの格納する値は2に
cube1.noの格納する値は1に
cube1.tateの格納する値は1に
cube1.yokoの格納する値は1に
cube1.takasaの格納する値は1に
なっていないかも
しれないということなんです。」
マックス「はえ???????」
solarplexuss「??????????」
ソーラー「
つまり
main関数内で変数宣言された
変数aを
自作関数内で定義された変数bに代入しても
変数aから変数bへ値渡しが行われるのみで
main関数内で変数宣言された
変数aに格納された数値は変化しませんでした。
同様に
クラスCubeのメンバ関数である自作関数display内の
a
no
tate
yoko
takasa
に
main関数内でオブジェクト宣言された
クラスCube型のオブジェクトcube1のメンバ変数
cube1.a
cube1.no
cube1.tate
cube1.yoko
cube1.takasa
が代入されても
クラスCube型のオブジェクトcube1のメンバ変数
cube1.a
cube1.no
cube1.tate
cube1.yoko
cube1.takasa
から
a
no
tate
yoko
takasa
に
値渡しが行われるのみで
main関数内でオブジェクト宣言された
クラスCube型のオブジェクトcube1のメンバ変数
cube1.a
cube1.no
cube1.tate
cube1.yoko
cube1.takasa
に格納される数値は
1
0.0
0.0
0.0
0.0
のまま
変化していないかもしれないということなんです。」
マックス「げええ それはないだろう」
ソーラー「そのことを確かめるために
今のプログラムのmain関数内に
cout <<"cube1.aの値はほんとに" <<cube1.a<< "になりました" << "\n";
cout << "立方体につけられたナンバーはほんとに" << cube1.no << "になりました" << "\n";
cout << "立方体の縦の長さはほんとに" << cube1.tate << "になりました" << "\n";
cout << "立方体の横の長さはほんとに" << cube1.yoko << "になりました" << "\n";
cout << "立方体の高さの長さはほんとに" << cube1.takasa << "になりました" << "\n";
を加えたものを実行してみたいと思います。
#include <iostream>
using namespace std;
class Cube {
public:
int no;
public:
float tate;
public:
float yoko;
public:
float takasa;
public:
Cube();
/*🌞🌞🌞クラスCubeのコンストラクタCube() のメンバ関数宣言を行っています*/
public:
void display(); //自作関数display()のクラスCubeのメンバ関数宣言を行っています
public:
static int a;
/*🌞🌞🌞ここですよ~ん🌞🌞🌞
静的メンバ変数aのCubeのメンバ変数宣言を行っています*/
};
Cube::Cube() {
no = 0;
tate = 0;
yoko = 0;
takasa = 0;
cout << "生成されたオブジェクトのメンバ変数を初期化しました" << "\n";
}
/*👆🌞
クラスのコンストラクタCube()の定義を行っています
🌞*/
void Cube::display() {
cout << a << "回目のオブジェクトcube1のメンバ関数cube1.display()を実行しました" << "\n";
a++;
cout << "cube1.aの値は" << a << "になりました" << "\n";
no++;
cout << "立方体につけられたナンバーは" << no << "です" << "\n";
tate++;
cout << "立方体の縦の長さは" << tate << "です" << "\n";
yoko++;
cout << "立方体の横の長さは" << yoko << "です" << "\n";
takasa++;
cout << "立方体の高さの長さは" << takasa << "です" << "\n";
}
//👆クラスCubeのメンバ関数となっている自作関数display()の定義をおこなっています
int Cube::a = 1;
//👆🌞🌞🌞ここです🌞🌞🌞静的メンバ変数aの初期化を行っています
//👆🌞🌞🌞静的メンバ変数aの格納する値は1になります
int main() {
Cube cube1;
//👆cube1のクラスCube型のオブジェクト宣言をおこなっています
/*🌞このとき オブジェクトcube1のコンストラクタが自動的に実行されています*/
cout << "オブジェクトcube1の静的メンバ変数cube1.aに代入された数値は" << cube1.a << "です" << "\n";
cube1.display();
cout << "cube1.aの値はほんとに" << cube1.a << "になりました" << "\n";
cout << "立方体につけられたナンバーはほんとに" << cube1.no << "になりました" << "\n";
cout << "立方体の縦の長さはほんとに" << cube1.tate << "になりました" << "\n";
cout << "立方体の横の長さはほんとに" << cube1.yoko << "になりました" << "\n";
cout << "立方体の高さの長さはほんとに" << cube1.takasa << "になりました" << "\n";
return 0;
}
プログラムの実行結果
生成されたオブジェクトのメンバ変数を初期化しました
オブジェクトcube1の静的メンバ変数cube1.aに代入された数値は1です
1回目のオブジェクトcube1のメンバ関数cube1.display()を実行しました
cube1.aの値は2になりました
立方体につけられたナンバーは1です
立方体の縦の長さは1です
立方体の横の長さは1です
立方体の高さの長さは1です
cube1.aの値はほんとに2になりました
立方体につけられたナンバーはほんとに1になりました
立方体の縦の長さはほんとに1になりました
立方体の横の長さはほんとに1になりました
立方体の高さの長さはほんとに1になりました
マックス「
ではなぜ
クラスCubeのメンバ関数である自作関数display()内の
a
no
tate
yoko
takasa
に
main関数内でオブジェクト宣言された
クラスCube型のオブジェクトcube1のメンバ変数
cube1.a
cube1.no
cube1.tate
cube1.yoko
cube1.takasa
が代入されているのに
クラスCube型のオブジェクトcube1のメンバ変数
cube1.a
cube1.no
cube1.tate
cube1.yoko
cube1.takasa
から
a
no
tate
yoko
takasa
へ
データだけが渡される値渡しが行われるようなことはなく
main関数内でオブジェクト宣言された
クラスCube型のオブジェクトcube1のメンバ変数
cube1.a
cube1.no
cube1.tate
cube1.yoko
cube1.takasa
に格納されていた数値データは
クラスCubeのメンバ関数である自作関数display()の操作を受けて
1
0.0
0.0
0.0
0.0
から
2.0
1.0
1.0
1.0
1.0
へ
変化したのか
ということだが・・・・・・
分からん😊
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
このプログラムの場合
クラスCubeのメンバ関数である自作関数display()内の
a
no
tate
yoko
takasa
に
main関数内でオブジェクト宣言された
別の変数ともいえる
クラスCube型のオブジェクトcube1のメンバ変数
cube1.a
cube1.no
cube1.tate
cube1.yoko
cube1.takasa
が
代入されているのではなく
クラスCubeのメンバ関数である自作関数display()内の
a
no
tate
yoko
takasa
は
クラスCube型のオブジェクトcube1のメンバ変数
cube1.a
cube1.no
cube1.tate
cube1.yoko
cube1.takasa
💖そのもの💖
というわけなのですね。
ですので
cube1.a
cube1.no
cube1.tate
cube1.yoko
cube1.takasa
は
自作関数display()の操作を
受けて
cube1.a
cube1.no
cube1.tate
cube1.yoko
cube1.takasa
に格納される値は
1
0.0
0.0
0.0
0.0
から
2
1.0
1.0
1.0
1.0
へ
変化するというわけです。
おまけの考察
クラスCubeのメンバ関数display()の定義
👇
void Cube::display() {
cout << a << "回目のオブジェクトcube1のメンバ関数display()を実行しました" << "\n";
a++;
cout << "cube1.aの値は" << a << "になりました" << "\n";
no++;
cout << "立方体につけられたナンバーは" << no << "です" << "\n";
tate++;
cout << "立方体の縦の長さは" << tate << "です" << "\n";
yoko++;
cout << "立方体の横の長さは" << yoko << "です" << "\n";
takasa++;
cout << "立方体の高さの長さは" << takasa << "です" << "\n";
}
👆
内で用いられている
クラスCubeのメンバ変数
a
no
tate
yoko
takasa
は
クラスCubeのメンバ関数display()の定義内で
変数宣言された変数ではなく
クラスCubeのメンバ関数display()の定義の外
Cubeのクラス宣言内で
変数宣言された変数です。
つまり
クラスCubeのメンバ変数
a
no
tate
yoko
takasa
は
自作関数である
display()内で変数宣言された
変数ではないので
自作関数display()内でのみ使用できる
変数ではないということです。
________________________________________________
通常
自作関数の定義内で変数宣言された変数は
自作関数内でのみ使用することができます。
自作関数の実行後は
自作関数の定義内で変数宣言された変数は
メモリから消去されることになります
________________________________________________
クラスCubeのメンバ変数
a
no
tate
yoko
takasa
は
Cubeのクラス宣言
👇
class Cube {
public:
int no;
public:
float tate;
public:
float yoko;
public:
float takasa;
public:
Cube();
/*🌞🌞🌞クラスCubeのコンストラクタCube() のメンバ関数宣言を行っています*/
public:
void display(); //自作関数display()のクラスCubeのメンバ関数宣言を行っています
public:
static int a;
/*🌞🌞🌞ここですよ~ん🌞🌞🌞
静的メンバ変数aのCubeのメンバ変数宣言を行っています*/
};
👆
に続く
クラスCubeのコンストラクタ
Cube()の定義内でも
クラスCubeのメンバ関数display()
の定義内でも使用され
main関数内の
オブジェクトcube1のメンバ関数
cube1.display()が実行されるとき
cube1.displayの定義内の
クラスCubeのメンバ変数
a
no
tate
yoko
takasa
に
cube1.a
cube1.no
cube1.tate
cube1.yoko
cube1.takasa
が代入されるという形で
使用されています。
Cubeのクラス宣言内で
public:
int no;
public:
float tate;
public:
float yoko;
public:
float takasa;
public:
static int a;
と変数宣言された
💖クラスCubeのメンバ変数💖
a
no
tate
yoko
takasa
は
💖💖💖まるで💖💖💖
💖メンバ変数宣言された行以下に作用する💖
💖グローバル変数のような働きをする💖
特殊な変数なのですね。
solarplexussより
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます