0

newを使用してオブジェクトを作成すると、そのオブジェクト はヒープに割り当てられます。しかし、インスタンス化するクラスのメンバーはどうなりますか?例えば、

class foo {
 Bar x;
 Bar *y;

 foo() {
   x = 10;
   y = new Bar();
 }
}

ここで、xはオブジェクトであり、yはBarのインスタンスです。それらは両方ともヒープに割り当てられていますか?したがって、foo Fのオブジェクトがメソッド内でローカルに作成された場合、Fがスコープ外になるとyはどうなりますか?

また、Fがヒープ上に作成された場合、 Fがぶら下がっていると結論付けるのはいつですか(誰もそれを指していない)?なぜなら、Fへの参照はないかもしれませんが、Yへの参照はあるかもしれません。

4

4 に答える 4

6

それらは、親オブジェクトと一緒に移動します。つまり、親がどのように初期化されたかに応じて、動的に割り当てられるか、自動保存期間が割り当てられます。ただし、必ずしもそれぞれを個別に割り当て解除する必要があるという意味ではありません。

xあなたの場合、親オブジェクトがであるときに自動的に割り当てが解除されます。ただし、y動的に割り当てられました。したがって、個別の割り当て解除が必要です。への呼び出しはnew、ある時点での呼び出しの後に続く必要がありますdelete。この基本的なルールは、これらの状況について推論するのに役立ちます。

余談ですが、動的に割り当てられたオブジェクトの割り当て解除を管理するには、RAII(リソース割り当ては初期化)と呼ばれるパターンを使用する必要があります(ただし、三つのルールを忘れないでください)。また、コンストラクターの本体を使用してオブジェクトを初期化する代わりに、初期化リストを使用する習慣を身に付ける必要があります。

class foo {
 Bar x;
 Bar *y;

 foo() : x(10), y(new Bar()) { }

 // who deallocates y here?  Again, look into RAII
}
于 2012-07-30T19:28:19.893 に答える
2

それらは両方ともヒープに割り当てられていますか?

はい。

したがって、foo Fのオブジェクトがメソッド内でローカルに作成された場合、Fがスコープ外になるとyはどうなりますか?

何もありません-クリーンアップを提供するデストラクタがないため、「y」が指すインスタンスは配置されたままになります。他の何かがそれを参照しない限り(そして後でそれをクリーンアップしない限り)、それは事実上メモリリークになります。

また、Fがヒープ上に作成された場合、Fがぶら下がっていると結論付けるのはいつですか(誰もそれを指していない)?

直接指し示すものがなくなるとすぐにぶら下がるでしょう。他の何かが指し示していても、到達できなくなっyたという事実は変わりません。F

この場合、実際に適切なファイナライズを使用する必要があるのはこのためです。deleteへのすべての呼び出しを一致させるための呼び出しがないとnew、メモリリークが発生します。

于 2012-07-30T19:28:33.743 に答える
0

xとはy、インスタンス化子が親オブジェクトを割り当てる場所に割り当てられますfoofooローカルとして割り当てられた場合、xとの両方yがスタックに割り当てられます。fooを介して割り当てられた場合new、両方がヒープに割り当てられます。

オブジェクトは、デフォルトのコンストラクターで経由して割り当てられるyため、のコンストラクターでポイントするように設定され、foo常にヒープに割り当てられます。new

にデストラクタが定義されていないためfoo、オブジェクトyポイントは常にリークします。メモリリークを防ぐために、オブジェクトfooが常に(nullでない場合)を指すデストラクタを作成する必要があります。実際には、デフォルトのコピー割り当てとクローンコンストラクターの問題を防ぐために、ベアポインターの代わりにスマートポインターがよく使用されます。deleteyy

于 2012-07-30T19:40:17.357 に答える
0

用語には少し混乱があります(Javalandが原因である可能性があります...)C ++では、変数は常に「値」であり、ポインターには「アドレス」である「値」があります。これ以上何もない。変数が参照であり、すべてのオブジェクトがオンヒープであるC#またはJavaとは完全に異なります。

ポインタを「値が別のオブジェクトのアドレスであるオブジェクト」と考えてください。その時点で、fooそれを使用して作成され、その中に残された2つのメンバーがあります。

  • x、それはインスタンス自体Barの内部で作成され、foo...
  • y、これはfooインスタンスに存在し、バーのアドレスです

含まれているアドレスyは、初期化/割り当てられているものによって異なります。

  • することができますnullptr
  • 別のBar既存のものにすることができます(ヒープ、スタック、またはメンバーによって異なります)
  • 別の新しく作成されたバーにすることができます(newサンプルのように、を介して)
  • することができます...x自体でさえ(経由&x
于 2012-07-30T19:40:25.230 に答える