1

自分の知識のいくつかのギャップを解消したい。これから。

例 (c#):

List<Person> names = new List<Person>();

Person friend = null;
for(int i = 0; i < 5; i++)
{
    friend = new Person();
    Person guy = new Person();

    guy.name = "Bob" + i;
    friend.name = "Bill" + i;

    names.Add(guy);
    names.Add(friend);
}

ここでは、スペースを節約するために、同じループで 2 つの Person オブジェクトを使用しています。

友人をインスタンス化するたびに、メモリ内の同じ場所を再利用し、存在する場合は既存の Person オブジェクトを上書きすることを理解しています。

一方、新しい「男」オブジェクトにはそれぞれ、新しいメモリの場所が割り当てられます。

これが正しい場合、これが間違っている場合は修正してください。これは、「guy」よりも「friend」を使用する方がメモリ効率が高いことを意味します。

「男」の方がいいというケースはありますか?コンストラクタの実装に依存する可能性はありますか?

4

4 に答える 4

9

友人をインスタンス化するたびに、メモリ内の同じ場所を再利用し、存在する場合は既存の Person オブジェクトを上書きすることを理解しています。

いいえ、そうではありません。変数の以前の値を上書きしていますが、それはオブジェクトではありません。それは単なるオブジェクトへの参照です。リスト内のオブジェクトへの別の参照があります。オブジェクト自体はまったく上書きされません。作成する各オブジェクトは、他のオブジェクトから独立しています。

変数をループ内で宣言するか、ループ外で宣言するかの違いに関しては、大きな違いはありません。いくつかの違いがあります:

  • ループの外側で宣言されている場合は、新しい値を割り当てる前にループ内で変数を使用できるため、前の値を確認できます。
  • ループの外側で宣言されている場合は、ループの後で変数を使用して、最後に割り当てられた値を読み取ることができます
  • ループの外で宣言され、ループで無名関数を使用する場合、すべての無名関数は同じ変数を取得します。ループ内にある場合、各無名関数は異なる変数をキャプチャします。現時点でこれらすべてがゴブルディグックのように聞こえる場合は、おそらく無視できます
  • ループ内で宣言されている場合は、別のブロックで同じ名前の別の変数を宣言できます。ループの外で宣言されている場合、それはできません。

私は通常、変数を最初に必要とする時点で、可能な限り最小のスコープで変数を宣言することをお勧めします。その方がコードがより明確になります。

于 2013-12-06T22:42:42.967 に答える
2

ループの内側と外側でオブジェクトを作成する場合のメモリの違いは何ですか?

Personいいえ、どちらの場合もループ内に新しいオブジェクトを作成しています。ループ内に 1 つの変数を作成し、ループ外に 1つの変数を作成するだけです。これら 2 つの唯一の違いは、ループが完了した後も、ループfriend内で最後に割り当てたインスタンスへの参照が含まれていることです。

友人をインスタンス化するたびに、メモリ内の同じ場所を再利用し、存在する場合は既存の Person オブジェクトを上書きすることを理解しています。

いいえ、そうではありません。をインスタンス化するたびPersonに、その新しいインスタンスをどこに格納するかは完全にランタイム次第です。以前のインスタンスを上書きするのではなく、新しいインスタンスを参照するために使用する変数を再利用するだけです。

インスタンスへのすべての参照が削除されると、ガベージ コレクターはその古いインスタンスに関連付けられたメモリを解放し、後でそのメモリを再利用できるようにします。ただし、ここでは、各インスタンスをリストに追加しているため、namesリストがクリアされるか破棄されるまで (および他の場所に存在する可能性のある他のインスタンス)、それらは収集されません。

于 2013-12-06T22:44:05.040 に答える
0

新しい友達を作成するとき、メモリの場所を再利用していません。新しいオブジェクトを作成し、そのアドレスをフレンド変数に割り当てます。したがって、以前の友人のことを「忘れる」ことになります。

したがって、メモリ効率は高くありません。また、for ループの後に friend を使用しない場合は、guy で行ったように、for 内で friend 変数を定義する方がクリーンです。

于 2013-12-06T22:41:27.867 に答える
0

友人をインスタンス化するたびに、メモリ内の同じ場所を再利用し、存在する場合は既存の Person オブジェクトを上書きすることを理解しています。

その理解は間違っています。フレンド変数からメモリ内のオブジェクトへの接続を切断しますが、メモリ内の以前のオブジェクトはまだ生きています。そのオブジェクトへの他の参照がない場合、コレクションの対象となりますが、コレクションがいつ行われるかは保証されません。この場合、(names コレクションを介して) 古いオブジェクトへの既存の参照が残っているため、コードの唯一の違いは、最後に作成されてfriend変数に割り当てられたオブジェクトが、ループの後で引き続きアクセスできることです。

于 2013-12-06T22:42:53.667 に答える