В C++, когда может две переменные того же имени быть видимым в том же объеме?

Вы можете использовать Bash для X в нотации $ {}, чтобы выполнить это:

for p in ${PATH//:/\n'} ; do
    echo $p;
done
6
задан Phil Miller 6 June 2009 в 00:07
поделиться

6 ответов

Это разрешено, поэтому вы можете безопасно игнорировать переопределение глобального идентификатора. По сути, вам нужно заботиться только о глобальных именах, которые вы действительно используете.

Предположим, что в вашем примере сначала была определена f () . Затем какой-то другой разработчик добавил глобальную декларацию. Добавив имя, f () , которое раньше работало, по-прежнему работает. Если переопределение было ошибкой, функция внезапно перестала бы работать, даже если она вообще ничего не делает с недавно добавленной глобальной переменной.

6
ответ дан 8 December 2019 в 02:35
поделиться

Что касается того, почему это разрешено: это совершенно верно.

Когда вы находитесь в своей функции f () , вы определяете локальную область видимости. Локальные области имеют приоритет над глобальной областью, поэтому определение вашей переменной «a» там «скрывает» глобальную int * a;

15
ответ дан 8 December 2019 в 02:35
поделиться

Многие языки допускают подобные вещи.
Обычно (по отношению ко всем языкам) наиболее локально определяемая переменная - это та, о которой вы тоже говорите. Из 20+ языков, которые я использовал, это очень распространено.

Также большинство языков позволяют вам явно ссылаться на язык во внешней области.
Например, C ++ позволяет вам указать переменную в глобальной области с помощью оператора ::.

#include  <iostream>


int a = 5;
int main()
{
    int a = 6;

    std::cout << a << "\n" << ::a << "\n";
            // Local
                           // global
}
4
ответ дан 8 December 2019 в 02:35
поделиться

Это совершенно верно, но я думаю, что с -Wall вы получите предупреждение только при затенении параметра.

Если вам нужны предупреждения при затенении любого типа переменной, Вы можете использовать ее на странице руководства g ++ :

   -Wshadow
       Warn whenever a local variable shadows another local variable, 
       parameter or global variable or whenever a built-in function is 
       shadowed.

Обратите внимание, что -Wshadow не включен в -Wall по умолчанию.

9
ответ дан 8 December 2019 в 02:35
поделиться

Как уже упоминалось другими, это совершенно законно и однозначно для компилятора.

Однако это одна из многих особенностей языков программирования, которая может вызвать путаницу или затруднить- найти ошибки. Поскольку было бы тривиально давать разные имена каждой из этих переменных, для ясности я всегда предлагаю это сделать.

0
ответ дан 8 December 2019 в 02:35
поделиться

Чтобы ответить, когда это разрешено: в основном в любых двух вложенных областях.

Например:

void foo() {
    int a;
    {
        int a;
    }
}

class Base {
    int a;
};
class Derived: public Base {
    int a; // Yes, the name Base::a is visible in the scope of Derived, even if private
};

class Foo() {
    int a;
    Foo(int a) : a(a) { } // Works OK
};

using std::swap;
void swap(MyClass& lhs, MyClass& rhs);
// Not strictly a variable, but name lookup in C++ happens before determining 
// what the name means.

Теперь ответ должен быть очевидным: наличие двух «вещей» с одним именем в том же объеме обычно допускается. Это возможно, потому что не более одного из имен фактически определено в этой области; другие были бы просто видимыми в этой области. Правила разрешения имен определяют, какое имя будет выбрано, если есть несколько кандидатов.

Вы действительно не хотите предупреждать каждый случай, когда компилятор выбирает одну из альтернатив. Это даст вам массу предупреждений о таких невинных вещах, как перегрузка и некоторый умный код шаблона.

1
ответ дан 8 December 2019 в 02:35
поделиться
Другие вопросы по тегам:

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