16

C++ では、シャドウされた変数名のスコープ解決 (「優先順位」) は何ですか? オンラインで簡潔な答えを見つけることができないようです。

例えば:

#include <iostream>

int shadowed = 1;

struct Foo
{
    Foo() : shadowed(2) {}

    void bar(int shadowed = 3)
    {
        std::cout << shadowed << std::endl;
            // What does this output?

        {
            int shadowed = 4;
            std::cout << shadowed << std::endl;
                // What does this output?
        }
    }

    int shadowed;
};


int main()
{
    Foo().bar();
}

変数が競合する可能性のある他のスコープは考えられません。見逃した場合はお知らせください。

メンバー関数shadow内での 4 つの変数すべての優先順位は?bar

4

2 に答える 2

31

最初の例は 3 を出力します。2 番目の例は 4 を出力します。

一般的な経験則では、ルックアップは「最もローカルな」変数から「最もローカルでない」変数へと進みます。したがって、ここでの優先順位は、ブロック -> ローカル -> クラス -> グローバルです。

また、シャドウ変数の最新バージョンに明示的にアクセスすることもできます

// See http://ideone.com/p8Ud5n
#include <iostream>

int shadowed = 1;

struct Foo
{
    int shadowed;
    Foo() : shadowed(2) {}
    void bar(int shadowed = 3);
};

void Foo::bar(int shadowed)
{
    std::cout << ::shadowed << std::endl; //Prints 1
    std::cout << this->shadowed << std::endl; //Prints 2
    std::cout << shadowed << std::endl; //Prints 3
    {
        int shadowed = 4;
        std::cout << ::shadowed << std::endl; //Prints 1
        std::cout << this->shadowed << std::endl; //Prints 2
        //It is not possible to print the argument version of shadowed
        //here.
        std::cout << shadowed << std::endl; //Prints 4
    }
}

int main()
{
    Foo().bar();
}
于 2010-05-10T17:31:48.063 に答える
5

3 を出力する必要があります。基本的なルールは、ほとんどの場合、ファイルをさかのぼって、コンパイラが確認した最新の定義 (編集: 範囲外にはなっていない) に移動することであり、それが使用されます。クラスにローカルな変数については、すべてのクラス変数がクラス定義の最初に定義されているかのように扱われることを除いて、同じに従います。ただし、これは多かれ少なかれクラスに固有のものであることに注意してください。たとえば、次のようなコードがあるとします。

int i;

int x() { 
    std::cout << i << '\n'; // prints 0;
    int i=1;
}

関数にローカルながありますiが、 が使用されている場所で見られる最新の定義coutはグローバルであるため、iその式の が参照するものです。ただし、これがクラス内にある場合:

int i;

class X { 
    void y() { std::cout << i << "\n"; }

    X() : i(2) {}

    int i;
};

その場合、その定義がまだ解析されていない場合でも、cout式は を参照します。X::iy

于 2010-05-10T17:43:13.340 に答える