Почему я могу переопределить const в меньшем объеме?

Я сейчас пробираюсь через Accelerated C ++, и я столкнулся с фундаментальным отсутствием понимания относительно области видимости и блоков кода с моей стороны.

В конце главы 1 приведено упражнение, в котором вам нужно решить, будет ли выполняться этот код:

#include <iostream>
#include <string>

int main()
{
{
const std::string s = "a string";
std::cout << s << std::endl;
{
const std::string s = "another string";
std::cout << s << std::endl;
}
}
return 0;
}

Я был уверен, что не будет, но это так. Мой опыт хобби в программировании заключался в том, что переменные, объявленные в блоке, доступны для других блоков, содержащихся в нем, но не для тех, которые находятся вне его.

И это должно быть как минимум наполовину верно, так как удаление второго объявления s приведет к двойному выводу «строки», создавая впечатление, что s, как объявлено во втором блоке, также присутствует в третьем блоке.

Я также попытался полностью удалить фигурные скобки третьего блока, что привело к ошибке компиляции, которую я ожидал в первую очередь. Но чем это отличается от объявления константы, которая уже существует в области действия третьего блока? Объявление константы переносится только на меньшую область, если в этой меньшей области нет второго объявления?

Я изучил все в книге вплоть до этого момента еще раз, чтобы увидеть, пропустил ли я что-то, но я не могу найти никакой информации о том, как на объявления переменных и const влияют фигурные скобки.

0

Решение

Это относится не только к константам, но это не имеет значения.

Но чем это отличается от объявления константы, которая уже существует в области действия третьего блока?

Вы вводите другую область, где переменная s не был определен, поэтому вполне законно определить его. Если вы удалите один, вы получите ошибку переопределения, потому что у вас уже есть s в том же объеме.

Объявление константы переносится только на меньшую область, если в этой меньшей области нет второго объявления?

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

// global scope
int a;
void f() {
int a = 0;
a = 4; // local 'a'.
::a = 4; // global 'a'.
}

Я не могу найти никакой информации о том, как переменные и объявления const зависят от фигурных скобок.

Фигурные скобки, как правило, вводят новую область действия (хотя есть некоторые исключения). Пока переменная с заданным именем не определена в текущей области, вы можете определить ее. Не имеет значения, есть ли переменная с тем же именем в области видимости за ее пределами, но ваш компилятор, скорее всего, предупредит вас об этом.

2

Другие решения

Java и C ++ являются одними из немногих, которые позволяют это.
C # не позволяет этого.
Это называется переменным теневым копированием. Если вы объявите переменную с тем же именем в меньшем внутреннем блоке, что и переменная внешних блоков, то вы получите маскирование имени.
Так что не имеет значения, что у вас есть переменная const, потому что внутренняя переменная — это вообще другая переменная.

3

По вопросам рекламы [email protected]