🌻天国にいけるC++言語入門🌻 進化し続けるオブジェクト指向プログラミング ver3.2307
オブジェクトaをオブジェクトbで初期化したとき もしくは オブジェクトaにオブジェクトbを代入したとき オブジェクトaとオブジェクトbの独立性は保たれます
オブジェクトaをオブジェクトbで初期化したとき もしくは オブジェクトaにオブジェクトbを代入したとき オブジェクトaとオブジェクトbの独立性は保たれます
🌞 🌞 🌞 🌞 🌞 🌞 🌞
😊オブジェクト宣言、初期化を同時に実行したとき😊
😊オブジェクトのコピーコンストラクタが実行される仕組み😊
😊わかったかな😊
🌞 🌞 🌞 🌞 🌞 🌞 🌞
マックス「まあ だいたいわかったかな
オブジェクト宣言をおこない
オブジェクトを生成したとき実行されるのがオブジェクトのコンストラクタ
オブジェクト宣言、初期化を同時に実行したとき
実行されるのが
オブジェクトのコピーコンストラクタってわけだ」
ソーラー「そうだね
そして
コピーコンストラクタについて学ぶ前に知っておいてほしいことがあります
それは
オブジェクトaにオブジェクトbを代入
もしくは
オブジェクトaをオブジェクトbで初期化したとき
オブジェクトaとオブジェクトbの独立性はたもたれる
ということなんです」
int(イント)「オブジェクトaとオブジェクトbの独立性?
って何のことかな?」
マックス「ふっ
オブジェクトaとオブジェクトbの独立性か(´▽`*)
なはは 簡単、簡単・・・???
何のことだ?」
ソーラー「オブジェクトaとオブジェクトbの独立性について
ご説明いたします
例えば
次のようなクラスSuutiがあるとします。
クラスSuutiのクラス宣言は次のようになっているとします
👇
class Suuti{
public:
int x;
};
👆
このクラスSuutiを用いたプログラムを実行してみます
#include <iostream>
using namespace std;
class Suuti{
public:
int x;
};
int main() {
Suuti b;
b.x = 1;
cout << b.x << "\n";
return 0;
}
プログラムの実行結果
1
ソーラー「うまく
数値データ1
を
コマンドプロンプト画面に表示することができました」
マックス「おおぅ
いい・・
めっちゃシンプルじゃないか( ^ω^)・・・」
ソーラー「
このプログラムでは
クラスSuuti型のオブジェクトbのメンバ変数b.xに
数値データ
1
が格納されています
次に
別のクラスSuuti型のオブジェクト宣言
Suuti a;
を実行して
生成される
クラスSuuti型のオブジェクトaのメンバ変数a.xには
数値データ
2
を格納したとします
このとき
クラスSuuti型のオブジェクトaのメンバ変数a.xに
格納されている数値データを
変更しても
クラスSuuti型のオブジェクトbのメンバ変数b.xに
格納されている数値データは変更されません
なぜなら
クラスSuuti型のオブジェクトaの管理しているメモリ
と
クラスSuuti型のオブジェクトbの管理しているメモリ
は独立していて
どちらかのメモリに格納されているデータを変更しても
お互いに影響をあたえあうことはないからですね」
マックス「なんだ
オブジェクトaとオブジェクトbが独立しているって
そ~いうことか
めっちゃ普通のことだな」
int(イント)「ばう、ばう(🐕の真似をしています)」
ソーラー「それでは
次に
aのクラスSuuti型のオブジェクト宣言、初期化
Suuti a=b;
を実行して
クラスSuuti型のオブジェクトaのメンバ変数a.xに
クラスSuuti型のオブジェクトbのメンバ変数b.xが格納している
数値データ
1
を
格納したとします」
マックス「ふみゅう」
てんC「
aのクラスSuuti型のオブジェクト宣言、クラスSuuti型のオブジェクトbによる初期化ですか・・・
コピーコンストラクタは設定されていないみたいですね
その場合
Suuti a=b;
を実行すると
クラスSuuti型のオブジェクトa
は
クラスSuuti型のオブジェクトbで初期化されることになります
このとき
🍎クラスSuuti型のオブジェクトaとクラスSuuti型のオブジェクトbの2つのオブジェクトが存在し🍎
クラスSuuti型のオブジェクトaのメンバ変数a.x には数値データ 1
クラスSuuti型のオブジェクトbのメンバ変数b.x には数値データ 1
が格納されているのですね
」
ソーラー「そうなんです
aのクラスSuuti型のオブジェクト宣言、クラスSuuti型のオブジェクトbによる初期化
Suuti a=b;
を実行して
クラスSuuti型のオブジェクトaのメンバ変数a.xに
クラスSuuti型のオブジェクトbのメンバ変数b.xに
格納されている数値データ1
を代入したわけです
次に
クラスSuuti型のオブジェクトaのメンバ変数a.xに
格納されている数値データを
変更しても
もちろん
クラスSuuti型のオブジェクトbのメンバ変数b.xに
格納されている数値データ
は変更されません
なぜなら
この場合も
クラスSuuti型のオブジェクトaの管理しているメモリ
と
クラスSuuti型のオブジェクトbの管理しているメモリ
は独立していて
お互いに影響をあたえあうことはないからですね」
マックス「そりゃあ そうだろう このお話は楽勝だな😊」
ソーラー「次に
例えば
次のようなクラスSuutitoMoji(数値と文字)があるとします。
クラスSuutitoMojiのクラス宣言は次のようになっているとします
class SuutitoMoji{
public:
int x;
public:
char* i;
};
このクラスSuutitoMojiを用いたプログラムを実行してみます
#include <iostream>
using namespace std;
class SuutitoMoji{
public:
int x;
public:
char* i;
};
int main() {
SuutitoMoji b;
b.x = 1;
b.i = "ねこねこ";
cout << b.x << "\n";
cout << b.i << "\n";
return 0;
}
プログラムの実行結果
1
ねこねこ
ソーラー「うまく
数値データ1
と
文字列ねこねこ
を
コマンドプロンプト画面に表示することができました」
マックス「
char* i;
って何のためにあるんだったかな~」
int(イント)「へ?」
ソーラー「
char* i;
だけを取り出して考えてみると
char* i;
は
iのchar*(キャラアスタリスク型)のポインタ変数宣言です
char* i;
により生成される
char*型(キャラアスタリスク型)のポインタ変数iを用いて
i="ねこねこ";
を実行することにより
文字列データ"ねこねこ"
を
メモリに格納することができます
このとき
char*型(キャラアスタリスク型)のポインタ変数iには
文字列データ"ねこねこ"
を
格納しているメモリ領域の先頭のメモリが格納されてるのでしたね
以上がポインタ変数を用いて文字列データをメモリに格納する方法だったね😊
ではでは・・・
お話は変わって
クラスSuutitoMojiのクラス宣言内で
iのchar*(キャラアスタリスク型)のポインタ変数宣言
char* i;
を
記述することにより
bのクラスSuutitoMoji型のオブジェクト宣言
SuutitoMoji b;
を実行した際
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.x
と
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.i
が
生成されます
この
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.i
を用いて
b.i = "ねこねこ";
と
文字列データ"ねこねこ"
を
メモリに格納することができます
このとき
文字列データ"ねこねこ"
を
格納しているメモリ領域の先頭のメモリのアドレス番号が
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iに格納されることになります
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iを用いて
cout << b.i << "\n";
を実行すると
ねこねこ
が
コマンドプロンプト画面に
表示されることになりますね」
マックス「おおぅ
いい・・ うむ
素晴らしい説明じゃないか( ^ω^)・・・」
ソーラー「
このプログラムでは
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.xには
数値データ
1
が
格納され
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iを用いて
文字列データ
"ねこねこ"
が
メモリに格納されています
(このとき
文字列データ"ねこねこ"
を
格納しているメモリ領域の先頭のメモリのアドレス番号が
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iに格納されることになります)
このとき
さらに
aのクラスSuutitoMoji型のオブジェクト宣言
SuutitoMoji a;
を実行すると
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.x
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.i
が生成されます
この時生成された
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.xに
数値データ
2
を格納し
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iをもちいて
文字列データ
"にゃんこ"
を
メモリに格納したとします
(このとき
文字列データ"にゃんこ"
を
格納しているメモリ領域の先頭のメモリのアドレス番号が
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iに格納されることになります)
このとき
クラスSuutitoMoji型のオブジェクト
格納されている数値データや
クラスSuutitoMoji型のオブジェクト
格納されている文字列データを
変更しても
クラスSuutitoMoji型のオブジェクト
格納されている数値データや
クラスSuutitoMoji型のオブジェクト
格納されている文字列データは変更されません
なぜなら
クラスSuutitoMoji型のオブジェクトaの管理しているメモリ
と
クラスSuutitoMoji型のオブジェクトbの管理しているメモリ
は独立していて
どちらのメモリに格納されたデータを変更しても
お互いに影響をあたえあうことはないからですね」
マックス「なんだ???
めっちゃ普通のことじゃないのか?
今更って感じだしぃ~~~
オブジェクトaとオブジェクトbが独立しているって
めっちゃ普通のことだな」
int(イント)「ばう、ばう(🐕の真似をしています)」
ソーラー「そうですね
オブジェクトaとオブジェクトbは完全に独立していますね
それではさらに
次に
aのクラスSuuti型のオブジェクト宣言、クラスSuuti型のオブジェクトbによる初期化
SuutitoMoji a=b;
を実行して
クラスSuuti型のオブジェクトaのメンバ変数a.xには
クラスSuuti型のオブジェクトbのメンバ変数b.xが格納している
数値データ
1
を
そして
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iには
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iの格納しているアドレス番号を
格納したとします」
マックス「ふみゅう」
てんC「
aのクラスSuutitoMoji型のオブジェクト宣言、クラスSuutitoMoji型のオブジェクトbによる初期化ですか
SuutitoMoji a=b;
を実行して
クラスSuutitoMoji型のオブジェクトa
を
クラスSuutitoMoji型のオブジェクトbで初期化しているのですね
このとき
🍎クラスSuutitoMoji型のオブジェクトaとクラスSuutitoMoji型のオブジェクトbの2つのオブジェクトが存在し🍎
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.xには数値データ1
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iには
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iの格納しているアドレス番号が
格納されているのですね
ということは
💖クラスSuutitoMoji型のオブジェクトaのメンバ変数a.i💖
と
💖クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iの格納している💖
🌞アドレス番号は同じ🌞
ということになりますね」
ソーラー「そうなんです
💖アドレス番号はオブジェクトaのメンバ変数a.i💖
と
💖アドレス番号はオブジェクトbのメンバ変数b.iの格納しているアドレス番号は💖
🌞同じ🌞
になっていますね
そして
もちろん
この状態でも
🌞この2つのオブジェクト🌞
🌞クラスSuutitoMoji型のオブジェクトaとクラスSuutitoMoji型のオブジェクトbは独立しています🌞
ですので
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iの格納しているアドレス番号を変更しても
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iの格納しているアドレス番号は変更されないし
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iの格納しているアドレス番号を変更しても
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iの格納しているアドレス番号は変更されません
まずは
準備完了だね
もう1回繰り返すと
SuutitoMoji a=b;
が実行された後
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.x
に格納されている数値データ
や
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iの格納しているアドレス番号
を変更しても
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.x
に格納されている数値データ
や
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iの格納しているアドレス番号
は変更されません」
マックス「そうだろう、そうだろう」
ソーラー「そのことを示すプログラムを実行してみます」
#include <iostream>
using namespace std;
class SuutitoMoji{
public:
int x;
public:
char* i;
};
int main() {
SuutitoMoji b;
b.x = 1;
b.i = "ねこねこ";
SuutitoMoji a=b;
cout << b.x << "\n";
cout << b.i << "\n";
cout << a.x << "\n";
cout << a.i << "\n";
b.x = 2;
b.i = "にゃんこ";
cout << b.x << "\n";
cout << b.i << "\n";
cout << a.x << "\n";
cout << a.i << "\n";
return 0;
}
プログラムの実行結果
1
ねこねこ
1
ねこねこ
2
にゃんこ
1
ねこねこ
ソーラー「確かに
b.x = 2;
を実行して
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.x
に格納されている数値データを
2
に変更し
b.i = "にゃんこ";
を実行することにより
文字列データ"にゃんこ”を格納しているメモリのアドレス番号を
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iに代入しても
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.x
に格納されている数値データ
と
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.i
に
格納されているアドレス番号は変更されません
だからこそ
b.x = 2;
b.i = "にゃんこ";
cout << b.x << "\n";
cout << b.i << "\n";
cout << a.x << "\n";
cout << a.i << "\n";
を実行したときの
cout << b.i << "\n";
のビルド実行結果は
にゃんこ
になっていても
cout << a.i << "\n";
のビルド実行結果は
ねこねこ
のままになっているわけです
cout << b.i << "\n";
は
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iが
格納しているアドレス番号の付いたメモリを先頭としたメモリ領域に
格納されている文字列データ
"にゃんこ"
を
表示し
cout << a.i << "\n";
は
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iが
格納しているアドレス番号の付いたメモリを先頭としたメモリ領域に
格納されている文字列データ
"ねこねこ"
を表示しています
もちろん
このとき
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.i
と
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.i
は独立していて
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iが
格納しているアドレス番号が変更されても
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.iが
格納しているアドレス番号は変更されないというわけです
クラスSuutitoMoji型のオブジェクトaの管理しているメモリ
と
クラスSuutitoMoji型のオブジェクトbの管理しているメモリ
は独立していて
お互いに影響をあたえあうことはないのですね」
マックス「おおっう
b.i = "にゃんこ";
を実行することにより
文字列データ"にゃんこ”を格納しているメモリ領域の先頭のメモリのアドレス番号が
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.iに代入される・・・か
なかなか凝ってるな
ふはは
だが
クラスSuutitoMoji型のオブジェクトaのメンバ変数a.i
と
クラスSuutitoMoji型のオブジェクトbのメンバ変数b.i
は独立しているというのは
そりゃあ そうだろう
これは・・・本気で楽勝だな😊」
マックス「もっと
今 行われていることを簡単に言えば
int型の変数a
と
int型の変数b
があったとして
int型の変数aに格納されている数値データを変更したとしても
int型の変数bに格納されている数値データは変更されないってことだろう」
ソーラー「そういうことなんです」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます