2012-01-17 61 views
0

このようなことは何ですか?同じオブジェクト/変数を複数回宣言するとどうなりますか?(初心者)

static int i; 

// wrapped in a big loop 
void update_text() 
{ 
    std::stringstream ss; // this gets called again and again 
    ++i; 
    ss << i; 
    text = new_text(ss.str()); // text and new_text are defined elsewhere 
    show_text(text); // so is this 
} 

は、新しいアドレスとすべてを持つスタック内に新しいインスタンスを作成しますか? char配列でsprintfを使うほうが賢明でしょうか?

答えて

6

関数が呼び出されるたびに、std::stringstream ssという新しいローカルインスタンスがスタックにプッシュされます。関数の終わりに、このインスタンスは破棄され、スタックからポップされます。

機能の範囲update_textは、特定の時点で、範囲内に識別子ssを持つ複数の変数を持っていません。したがって、update_textの範囲内には、ssという識別子が1つしかありません。

文字配列は違いはありません。関数が呼び出されるたびに、静的に割り当てられたchar配列はスタックにプッシュされ、最後にポップされます。動的メモリを使用して文字配列を動的に割り当てると、関数が呼び出されるたびにnewdelete文が実行され、この文字配列へのポインタはプッシュされてスタックからポップされます。 std::stringstreamは既に内部でnewdeleteを処理しています。

複数回が次のようになり、オブジェクトが宣言:

void Function() 
{ 
    int x; 
    int x; 
} 

これは、コンパイルエラーが発生します。

が警告され、これはしかし、有効です。

void Function() 
{ 
    int x; 
    if(true) 
    { 
     int x; 
    } 
} 

2つの変数が異なるスコープであるため。2番目のxは、そのifステートメント内にのみ存在します。このように、コンパイラは、その宣言の後でそのスコープ内のxへの参照が2番目のxを参照すると推論することができます。タイプは重要ではないことに注意してください。重要な識別子または「名前」です。

0

小文字:オブジェクトを複数回宣言するのではなく、オブジェクトが複数回初期化される位置に遭遇することです。

だからあなたの本当の質問に答えるために:はい、それはssの新しいインスタンスを作成しますが、それがループのチャンスから呼ばれていた場合に関数が(が呼ばれるたびにアドレスが実際に同じになるということですが、それは本当にいけません問題はプログラマに)。

2番目の質問については、sprintfをchar配列に使用するほうが賢明でしょうか?もしあなたがC++を初めてお使いの方であれば、sprintfはより危険な形になっていますので、streams(型が不足している、オーバーフローのリスクがあります)ということから、この回答はノーです。実際の答えはそれに依存するでしょう。 stringstreamsを使用して得られるパフォーマンスが、あなたの目的には不十分である(まれに起こるはずがありません)場合は、sprintfを使用してください。さらにstringstreamsを再利用すると、毎回新しいものを作成する際のオーバーヘッドが軽減されることに注意してください(intをストリーミングする場合に重要です)。このタイプのキャストについては、Boost.Lexical_Castもご覧ください。彼らのthe performance section of there documentationによるとsprintfのtypesafety(およびバッファオーバーフローの危険性)の不在を露呈させることなく、intからstringへの変換(自分でテストしていないので、保証はありません)の場合はsprintfと同じくらい速いはずです。 C++ 11にもがあります。これは、安全を諦めることなく変換を行います(ただし、boost :: lexical_cast`よりははるかに柔軟性がありません)。

+0

ssの新しいインスタンスが作成されると、新しいメモリまたはスペースが使用されますか? – john

+0

@john:a)どうして気になりますか? b)これは、関数が呼び出されたスタックアドレスに対応するスタックアドレスに置かれます。これは、以前のインスタンスと同じでもかまいませんが、必ずしもそうである必要はありません。作成時に内部バッファをヒープに割り当てます。そのため、関数が呼び出されるたびに内部バッファが割り当てられますが、メモリシステムが同じメモリチャンクを与えるかどうかは誰にも分かりません。だから毎回作成されますが、それはメモリを再利用するかもしれません(または気にしない人)。 – Grizzly

関連する問題