2012-02-15 18 views
2

はの一つは、このようなスコープ曖昧

class Foo { 
public: 
    void bar(); 
    operator bool() const { return true; } 
}; 

としてクラスFooのを持っているとしましょうならば、一つは

if(Foo foo = Foo()) 
{ 
    if(Foo foo = Foo()) 
    { 
    foo.bar(); 
    } 
} 

は、今私は(ここで起こっスコープ解決を把握トラブルを抱えていないことができますI fooの再宣言のコンパイラエラーが予想されます)。

私はfoo.bar()が2番目のfoo(そのスコープは "より近い")で実行されると期待していますが、実際に最初のfooとは異なるオブジェクトであることを保証していますか?さらに、それぞれのifブロックの終わりにそれぞれ独立して配置されていますか(デストラクタが呼び出されますか?)私はfoo.bar()は第FOO上で実行することを期待

+0

ここではあいまいさはありません。 Standardは、* scope *と* potential scope *の違いを明確に示しています。しかし、それは良いアイデアにはなりません、しかし、これをやってはいけません! –

+0

私はあまりにもあいまいであると私はそれを意味! ^^ –

+0

これは_シャドウイングと呼ばれ、一般的には良い考えではありません。とにかく、時にはそれを行うこともありますが、 'struct s {int(int n):n(n){} int n; }; ' – wilhelmtell

答えて

7

C++はネストされたスコープの内部にあるので、あいまいさがない限り、同じ名前の変数を宣言することは非常にうれしいです。あなたは

正しいですが、私はそれが実際だとgaranteedています私はfoo.bar()は二FOO上で実行することを期待

(その範囲は "近い" です)

最初のfooとは異なるオブジェクトですか?

はい

さらに、それらは、それぞれ独立に、その場合の各ブロックの終わりに(それらのデストラクタが呼び出さ)が配置されていますか?

はい

4

(その範囲が "近い" である)

正しいです。

しかし、実際には最初のfooとは異なるオブジェクトであることを保証していますか?

はい。

さらに、それぞれのifブロックの最後にそれぞれ独立して(デストラクタが呼び出されて)配置されていますか?

はい、あなたはそれを持っています。

+0

なぜコンパイラエラーはありませんか? – BlackBear

+1

@BlackBear:なぜそこにはありますか?同じ範囲*での再定義*ではありません。 –

+0

Matt Tが説明したように(http://stackoverflow.com/a/9301681/129655参照)、C++は入れ子スコープ内にある限り同じ名前の新しい変数でも問題ありません。同じスコープ内にある場合は、2番目の宣言が問題になります。 –

2

あなたの例では文とクラスオブジェクトの初期化は、内側のスコープでの宣言は完全に合法であるということです関連するポイントを、不明瞭と外側のスコープ内で同じ名前の宣言を非表示にする傾向がある場合の使用。

おそらく明確例:

#include <iostream> 
int main() { 
    const int x = 10; 
    std::cout << "outer x is " << x << "\n"; 
    { 
     const double x = 12.34; 
     std::cout << " inner x is " << x << " (it hides the outer x)\n"; 
    } 
    std::cout << "outer x is still " << x << " (inner x no longer exists)\n"; 
} 

出力である:内側および外側x sがあっても、同じタイプのない

outer x is 10 
    inner x is 12.34 (it hides the outer x) 
outer x is still 10 (inner x no longer exists) 

留意されたいです。

これは合法ですが、通常はお勧めできません。コンパイラには問題はありませんが、人間の読者には混乱することがあります。 g++ -Wshadowでコンパイルすると、警告が表示されます。

c.cpp: In function ‘int main()’: 
c.cpp:6:22: warning: declaration of ‘x’ shadows a previous local 
c.cpp:3:15: warning: shadowed declaration is here