今回はプログラムとメモリの関係について、記載しようと思います。スタック領域、ヒープ領域等の細かい話ではなく、もう少し感覚的な話をしたいと思います。
クラスを勉強していると本等で必ず出てきますね。クラスは書いただけじゃだめだよ、インスタンスにしないと意味ないからね、という説明。この説明では勉強中の方はよくわからないと思います。この辺りの理解の助けとなれば幸いです。
ソフトウェアはデジタル、結局は0か1
まず、私たちはPython等の言語でコードを記載していますが、これはコンパイラによって機械語に置き換えられます。機械語とは何かと言うと0 or 1の羅列です。例えば、"10"という数値は"00001010"となります。私が書いているプログラムは結局、0 or 1に変換されるのです。if~やfor~も信じられないかもしれませんが、最終的には0 or 1に変換されます。
メモリの使われ方
そして、もうひとつ大事なのがアドレスです。メモリにはアドレスと上記の0 or 1のデータを結び付けられてセットされます。
何か変数を作成したとします。そうすると、どこかのアドレスに変数のデータがセットされます。そして、そのデータにどうやってアクセスするかと言うと、アドレスを頼りにデータにアクセスします。
変数も関数もクラスも基本的に、上記と同じ仕組みになります。関数の先頭アドレス、クラスの先頭アドレスを基に関数を実行したり、クラスのメンバにアクセスします。
インスタンスとは
クラスをメモリ上に展開するにはどうしたらよいのでしょうか?それがまさにインスタンスを作成するという意味です。a = new クラス名() なんていう書き方をよくしますが、Pythonでは a = クラス名()だけでインスタンスを作ることができます。これで初めてメモリ上に展開されます。
クラスは複数のインスタンスを作成することが可能です。
a = クラス名()
b = クラス名()
aというインスタンスと、bというインスタンスが作成されます。これはメモリ上では別々のアドレスと領域になります。ですので、aのクラスのメンバ変数に何か設定したとしても、bのメンバ変数には何も影響はありません。aとbは全く別物なのです。
参照渡しとは
よく値渡しか参照渡しか、という話があると思いますが、オブジェクト指向言語は基本的に参照渡しと考えて良いと思います。
参照渡しとは何かというと、関数の引数にクラス名を書いたときに、クラスのメモリ領域全部をコピーすることはしません。クラスの先頭アドレスだけを渡し、アドレスからクラスのメンバにアクセスする方法です。アドレスしか渡していないので、高速です。
値渡し(コピー渡し)をするとメモリをどんどん使います。また処理に時間がかかりますので、普通に書けば、参照渡しです。意図的に値渡しにしたいときは、使用している言語の書き方に沿って書く必要があるはすです。