2011-01-18 10 views
1

コースの割り当てを行いながらC++を学んでいるときに、スタック割り当てと動的割り当てをいつ使うべきかを読んでいました。私は、多くの場合、スタック割り当てを使う方が簡単で、より良いことを認識しています。しかし、私が困惑している単純な状況があります。C++ループスタック割り当て

あなたはループを持っているとしましょう:

for(int i = 0; i < 10; i++) 
{ 
    MyObject obj(file); 
    obj.doSomething(); 
} 

さて問題は、オブジェクトの状態が含まれている場合は1から10ゴマの反復を反復しながら、それはそれに状態を保持します(同じオブジェクトのまま)ということです。たぶんJava/C#の背景から来て、間違った方向に私を取得します。しかし、私はこれを解決する2つの方法しか見ません:

  1. ダイナミックメモリの使用。
  2. ファイルをコンストラクタに渡すのではなく、doSomething(file)のメソッドに渡しますが、ファイルオブジェクトを操作するメソッドが複数ある場合は、これはあまり役に立ちません。 doSomethingElse(file)

あなたはこのような状況で何をするのですか、まったくそのような状況になることはありませんか?

更新: 私は間違っていると分かり、期待通りに動作しています。下の寝台をチェックしてください!ありがとうすべて

+0

「MyObject obj(file);」をダイナミックメモリに置き換えても、スコープのために状態は保持されません。 –

答えて

5

投稿したコードでは、objは繰り返しの間に状態を維持しません。

for(int i = 0; i < 10; i++) 
{  
    MyObject obj(file); //obj enters scope, constructor is called with 'file' 
    obj.doSomething(); 
} //obj loses scope, destructor is called 

この例では、objは毎回異なるオブジェクトです。以前のオブジェクトと同じ 'スタック'メモリロケーションを使用している可能性がありますが、クラスデストラクタとコンストラクタは反復の間に呼び出されます。

オブジェクトを1回だけ作成して繰り返し使用する場合は、ループの前に構築します。

function(file) 
{ 
    MyObject obj(file); //obj enters scope, constructor is called with 'file' 

    for(int i = 0; i < 10; i++) 
    {  
     obj.doSomething(); //Same object used every iteration 
    } 

} //obj loses scope, destructor is called 
+0

これは私が期待する動作ですが、私はコンストラクタが呼び出されていないデバッグ? VC++を使用して –

+0

私は最適化を無効にしてデバッグモードになっていることを確認します。コールはコンパイラによって最適化されます。 – James

+0

これは感謝していたことでした:D –

1

宣言を含む行に到達し、各ループ反復の終わりに破棄される(そのデストラクタが呼び出される)ときに、このループでループするたびにobjが作成されます(そのコンストラクタが呼び出されます)。

あなたはそれを一度に作成することにしたい、それがループの外にそれを宣言し、ループの繰り返しの上にその状態を保存している場合:

MyObject obj(file); 
for (int i = 0; i < 10; i++) 
{ 
    obj.doSomething(); 
} 

あなたは、このような複数の反復間で使用したのと同じオブジェクトを持っている必要がある場合(ファイルを変更するなどして)反復処理中にオブジェクトの状態を変更する必要がある場合は、その状態を変更できるメンバ関数が必要です(useThisFile(file)などの専用メンバ関数またはメンバへの追加パラメータ機能はdoSomething(file)のように使用されています)。

0

まだ周囲のスタックにオブジェクトを割り当てて、後で何を達成するのではないでしょうか?

MyObject obj(file); 
for (int i = 0; i < 10; i++) 
{ 
    obj.doSomething(); 
} 
0

上記のコードでは、objはループの1回の反復の範囲内で作成され、その最後で終了します。これは、Javaの場合、MyObject obj = new MyObject()を同じ場所に配置した場合と同じです。ファイルの状態を変更しない限り、情報はループの反復から他の反復に移行しません。

自分自身を納得させるには、ループの "ボディ"として関数呼び出しを配置し​​ます。その関数では、変数をスタックに作成します。変数は、この関数が実行されている間のみ有効です。

0

objは、すべての反復の最後に割り当て解除されます。そのデストラクタも10回呼び出されます。限り、クラスのデストラクタが適切にdeleteコンストラクタによって作成された限り、あなたは大丈夫でしょう。

ループに入る前にobjを一度だけ宣言したいと思うかもしれません。