Я сейчас пробираюсь через 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 влияют фигурные скобки.
Это относится не только к константам, но это не имеет значения.
Но чем это отличается от объявления константы, которая уже существует в области действия третьего блока?
Вы вводите другую область, где переменная s
не был определен, поэтому вполне законно определить его. Если вы удалите один, вы получите ошибку переопределения, потому что у вас уже есть s
в том же объеме.
Объявление константы переносится только на меньшую область, если в этой меньшей области нет второго объявления?
На самом деле, нет. Ваш второй s
является слежка первый. Технически они оба существуют, но у вас нет возможности получить доступ к первому. Иногда вы делаете это с помощью оператора разрешения области действия, но в вашем случае нет.
// global scope
int a;
void f() {
int a = 0;
a = 4; // local 'a'.
::a = 4; // global 'a'.
}
Я не могу найти никакой информации о том, как переменные и объявления const зависят от фигурных скобок.
Фигурные скобки, как правило, вводят новую область действия (хотя есть некоторые исключения). Пока переменная с заданным именем не определена в текущей области, вы можете определить ее. Не имеет значения, есть ли переменная с тем же именем в области видимости за ее пределами, но ваш компилятор, скорее всего, предупредит вас об этом.
Java и C ++ являются одними из немногих, которые позволяют это.
C # не позволяет этого.
Это называется переменным теневым копированием. Если вы объявите переменную с тем же именем в меньшем внутреннем блоке, что и переменная внешних блоков, то вы получите маскирование имени.
Так что не имеет значения, что у вас есть переменная const, потому что внутренняя переменная — это вообще другая переменная.