В 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
функция членства?
Ваш первый пример выводит 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();
}
Он должен распечатать 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
анализируется.