В C++, каково разрешение объема (“порядок очередности”) для затененных имен переменной?

В C++, каково разрешение объема ("порядок очередности") для затененных имен переменной? Я, может казаться, не нахожу краткий ответ онлайн.

Например:

#include 

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 переменные, когда в bar функция членства?

16
задан Emile Cormier 10 May 2010 в 18:21
поделиться

2 ответа

Ваш первый пример выводит 3. Ваш второй выводит 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();
}
31
ответ дан 30 November 2019 в 16:49
поделиться

Он должен распечатать 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 :: i , даже если его определение еще не было видно, когда y анализируется.

5
ответ дан 30 November 2019 в 16:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: