|
■No100840 (しーや さん) に返信 >>Other2インスタンスは、classA と classB の両方から参照されている状態です。 「クラス」と「インスタンス」の違いは分かりますか?
> Other2はOtherクラスで、Other1は無くなった。いう考え方は正しいですか? 無くなったと言えなくも無いですが、Other が struct ではなく class なのであれば、 「どの変数からも参照されていない状態になった」という状況が近いです。
参照されなくなったからと言って、その時点で直ちに消えるわけではありません。 この時点では、誰にも利用されない未使用状態のまま、メモリ上に残った状態となります。 ただ、そういった未使用のインスタンスは、その後、自動的に処分されて 消失する仕組みになっていますので、結果的には無くなったと言うこともできるかと。
---
int a = 1; a = 2; この場合、a は 1 という情報を忘れて、2 という情報値を保持している状態になりました。
int a = 1; int b = 2; a = b; この場合も、a が保持していた 1 という情報は失われ、a は 2 という情報値を保持している状態に変化します。
Other classA = new Other(1); Other classB = new Other(2); classA = classB; この場合、classA は Other1 という情報を忘れて、Other2 という情報を保持している状態になりました。 ここまでは、値型でも参照型でも大差ありません。
問題はそのあと、 classA.Value = 99; のように、そのメンバーを書き換えた場合の振る舞いです。
Other が struct(値型) であった場合は、「classA = classB;」というのは 値データそのものをコピーする動作となります。 コピーされた別のデータの Value メンバーを書き換えても、 コピー元となった classB の Value は変化しません。
一方、Other が class(参照型) であった場合は、「classA = classB;」というのは インスタンスのコピーではなく、そのインスタンスの「参照情報」をコピーする動作となります。 参照がコピーされたとしても、同じ実体(インスタンス)を複数の変数から参照しているだけなので、 classA.Value を書き換えると、同じ実体の情報を見ている classB.Value も連動して変化します。
>>ただしそれは、Other の型が参照型(たとえば class)だった場合の話。 >>Other が値型(たとえば struct)だった場合には、 >>classA にセットされるのは Other2 インスタンスへの参照ではなく、 >>Other2 の値をコピーしたものがセットされます。 > 例外の解説助かります。
たとえば「配列」は「参照型」なので、こういう動きをします。
int[] ary1 = { 11, 22, 33, 44 }; // 4 つの要素を持った配列を 1 つ作る int[] ary2 = ary1; // その配列を 変数 ary2 からも参照できる状態にする(参照情報がコピーされただけで、参照先の実体は複製されていない) ary1[0] = 9; // ary1 の先頭要素を 11 から 9 に変更する int result = ary2[0]; // ary2[0] も 9 に変化している。(ary1 と ary2 は、同じ配列を参照している) // この場合、配列の実体は最初に作った 1 つしかなく、それを ary1 と ary2 から参照している状態。
-----
参照型をコピーする場合は、複製するためのメソッド等を呼ぶなどの手続きが必要です。
int[] ary1 = { 11, 22, 33, 44 }; // 4 つの要素を持った配列を 1 つ作る int[] ary2 = ary1.ToArray(); // Clone メソッドあるいは ToArray メソッドを使い、同じ情報をもった別の配列をもう 1 つ作る(複製体を作成したということ) ary1[0] = 9; // ary1 の先頭要素を 11 から 9 に変更する int result = ary2[0]; // 今度は ary2[0] は 11 のまま。(ary1 と ary2 は異なる配列を参照している)
|