В С++, каково разрешение области ( "порядок приоритета" ) для теневых имен переменных?
В С++, каково разрешение области ( "порядок приоритета" ) для shadowed имена переменных? Кажется, я не могу найти краткий ответ в Интернете.
Например:
#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
, когда внутри функции члена bar
?
Ответы
Ответ 1
Ваш первый пример выводит 3. Ваши второй выходы 4.
Общее правило заключается в том, что поиск происходит от "самой локальной" до "наименее локальной" переменной. Поэтому приоритет здесь - block → local → class → global.
Вы также можете получить доступ к each в большинстве версий скрытой переменной:
// 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();
}
Ответ 2
Он должен распечатать 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
анализируется.