3

以下の例は、エラーのある最後の行を除いて正常にコンパイルされますが、スコープ内のこの「スコープ」のインとアウトを知りたいですか? もしあれば、これの用語も。

次のブラケットを検討してください。

void func()
{

    int i = 0;

    { // nice comment to describe this scope

        while( i < 10 )
            ++i;

    }

    { // nice comment to describe this scope

        int j= 0;
        while( j< 10 )
            ++j;

    }

    i = 0; // OK
    // j = 0; // error C2065

}

このことを考慮:

error C2065: 'j' : undeclared identifier

編集: 受け入れられた回答bitmaskからのものですが、誰もがanio回答のコンテキストに配置する必要があると思います。特に、引用:「おそらく、関数を2つの関数に分割する必要があります」

4

5 に答える 5

7

してください。ぜひ!

データを可能な限りローカルに保ち、可能な限り const に保つことには、主に 2 つの利点があります。

  • 副作用が減少し、コードがより機能的になります
  • 複雑なオブジェクトでは、デストラクタは、データが不要になるとすぐに、関数内の早い段階で呼び出すことができます

さらに、これは、関数の特定の部分が行う仕事を要約するドキュメントに役立ちます。

これは明示的またはダミーのスコープと呼ばれていると聞いたことがあります。

于 2012-08-23T21:45:28.367 に答える
6

個人的には、関数内にスコープを追加することにはあまり価値がありません。関数の一部を分離するためにこれに依存している場合は、おそらく関数を 2 つの関数に分割する必要があります。小さい関数は大きい関数よりも優れています。小さくて分かりやすい機能を持つように努めるべきです。

関数内でのスコープの正当な用途の 1 つは、ロックの期間を制限することです。

int doX() 
{

 // Do some work

  { 
  //Acquire lock


  } // Lock automatically released because of RAII
}

内部スコープは、ロックが保持されるコードを効果的に制限します。これは一般的なやり方だと思います。

于 2012-08-23T21:45:38.193 に答える
4

はい、間違いなく - 常に変数を可能な限りローカルに保つことは素晴らしい習慣です! いくつかの例:

for (std::string line; std::getline(std::cin, line); )     // does not
{                                                          // leak "line"
    // process "line"                                      // into ambient
}                                                          // scope

int result;

{                                        // putting this in a separate scope
    int a = foo();                       // allows us to copy/paste the entire
    a += 3;                              // block without worrying about
    int b = bar(a);                      // repeated declarators
    result *= (a + 2*b);
}

{                                        // ...and we never really needed
    int a = foo();                       // a and b outside of this anyway!
    a += 3;
    int b = bar(a);
    result *= (a + 2*b);
}

同期のためにスコープが必要な場合があり、クリティカル セクションをできるだけ短くしたい場合があります。

int global_counter = 0;
std::mutex gctr_mx;

void I_run_many_times_concurrently()
{
    int a = expensive_computation();

    {
        std::lock_guard<std::mutex> _(gctr_mx);
        global_counter += a;
    }

    expensive_cleanup();
}
于 2012-08-23T22:00:10.223 に答える
3

明示的なスコープは通常、コメントの目的で実行されませんが、コードが読みやすくなると思われる場合は、それを実行しても害はありません。

一般的な使用法は、名前の衝突を回避し、デストラクタが呼び出されるタイミングを制御することです。

于 2012-08-23T21:46:29.373 に答える
2

中括弧のペアはスコープを定義します。スコープ内で宣言または定義された名前は、そのスコープ外では表示jされません。そのため、最後に定義されていません。スコープ内の名前が以前に定義された名前と同じであり、そのスコープ外にある場合、外部の名前は非表示になります。

于 2012-08-23T21:48:39.350 に答える