4

C++ コード:

person* NewPerson(void)
{
  person p;
  /* ... */
  return &p; //return pointer to person.
}

C# コード:

person NewPerson()
{
  return new person(); //return reference to person.
}

この権利を理解していれば、C++ の例は適切ではありません。これは、pが範囲外になり、関数がワイルド ポインター (ダングリング ポインター) を返すためです。

C# の例は問題ありません。参照がある限り、匿名の新しい人物はスコープ内に留まるからです。(呼び出し関数は 1 つ取得します。)

私はこれを正しく理解しましたか?

4

7 に答える 7

4

「p」がスコープ外になり、関数が無効なポインターを返すため、C++ の例は適切ではありません。

正しい。

C# の例は問題ありません。匿名の「新しい人」は、それへの参照がある限りスコープ内に留まるからです。

それは多かれ少なかれ正しいですが、あなたの用語はまったく正しくありません。C#のスコープは、修飾されていない名前を使用できるテキストの領域です。ここのオブジェクトには名前がありません。ライフタイムとは、ストレージの場所が有効であることが保証されるランタイムの期間です。 スコープとライフタイムはつながっています。コントロールがスコープに関連付けられたコードを残す場合、そのスコープ内で宣言されたローカルの有効期間は通常、終了することが許可されます。(ただし、ローカルの有効期間が、制御がスコープ内にある時間よりも長いまたは短い状況があります。)

また、それを維持するのは Person オブジェクトへの参照ではないことに注意してください参照はルート化されている必要があります。相互に参照する 2 つの Person オブジェクトを持つことができますが、それ以外の場合は到達できません。それぞれが参照を持っているという事実は、それらを存続させません。参照の 1 つがルート化されている必要があります。

于 2011-12-10T15:47:07.097 に答える
2

この例のスコープ ルールは類似していますが、C# では、返された値が何かに割り当てられている場合、何かがそれへの参照を保持している限り、ガベージ コレクションは行われません。何かに割り当てられていない場合、それへの参照を保持するものはなく、コレクターが次に実行されるときにガベージコレクションされます

于 2011-12-10T12:01:16.923 に答える
2
person* NewPerson(void)
{
  person p();
  /* ... */
  return &p; //return pointer to person.
}

pではありません。最も厄介な parsepersonを参照してください。そのため、コンパイラ エラーが発生します。

残りについては、はい、あなたは正しいです。

于 2011-12-10T12:02:15.973 に答える
1

はい、正解です。

ただし、C ++では、実際にこのようにします

person NewPerson()
{
  person p;
  /* ... */
  return p; //return person.
}

そして、電話でそれをかなり確認してください

person x = NewPerson();

コンパイラは、戻り値のコピーを最適化します。

于 2011-12-10T12:16:54.137 に答える
1

C++ では、その 'p' はスタック上に存在するため、関数が戻ると上書きされます。C# では、ガベージ コレクターは、最後の参照が失われるまでそれを上書きしないことを認識しています。

(「clobber」はここでは大まかに使用されています... :p)

于 2011-12-10T12:01:05.190 に答える
0

私はこれを正しく理解しましたか?

はい。

ところで:C ++の人ではp(); 関数を宣言し、person のデフォルトの ctor を呼び出しません。人 p; と書くだけです。

于 2011-12-10T12:02:45.020 に答える
0

関数が終了すると破棄される一時への参照を返すため、これは C++ では機能しません。ヒープ上に人を作成しnew、それへの参照を返す必要があります。

于 2011-12-10T12:02:49.937 に答える