Я немного смущен глобальными константами. Насколько я понимаю (начальный уровень), «глобальные» переменные определяются вне блока и имеют область действия программы (источник: http://www.learncpp.com/cpp-tutorial/42-global-variables/). Но программа:
#include <iostream>
const double x=1.5;
int main(){
std::cout << "1) x=" << x << std::endl;
double x=2.5;
std::cout << "2) x=" << x << std::endl;
//const double x=3.5;
return 0;
}
компилируется в g ++ (GCC, последняя 64-битная версия) без каких-либо проблем, даже с -Wall.
Выход:
1) x=1.5
2) x=2.5
Это смущает меня. Тот факт, что первый cout оценивает, означает, что main распознает «x» как «глобальную» переменную (она не была определена в области видимости main). Если это так, почему это позволяет мне переопределить «х»?
Затем, если вы раскомментируете закомментированное третье объявление, g ++ выдает ошибку объявления. Это означает, что мое первое объявление не могло быть «глобальным» в том смысле, в котором я определил: S
редактировать: хорошо, вопрос не имеет ничего общего с глобальными переменными, но объем: например, та же проблема в http://pastebin.com/raw.php?i=V5xni19M
#include <iostream>
const double x=1.5;
На данный момент в коде есть один объект с именем x
в глобальном масштабе, и это имеет тип const double
,
int main(){
std::cout << "1) x=" << x << std::endl;
На данный момент, есть только один x
видимый (глобальный), так вот как называется x
относится к.
double x=2.5;
На данный момент в коде вы ввели объект с именем x
в сферу main()
, Эта область вложена в глобальную область, так что теперь у вас есть два объекта с именем x
:
x
в глобальной области видимости const double
x
в объеме main()
типа double
Местный x
скрывает глобальный x
, Если вы хотите получить доступ к глобальной x
внутри main()
, вы можете сослаться на это как ::x
,
std::cout << "2) x=" << x << std::endl;
double x=3.5; //uncommented
Нет, ты пытаешься представить другой названный объект x
в сферу main()
, Это невозможно, там уже есть один x
в этой области, поэтому он терпит неудачу.
Второй x
это не переопределение. это hiding
глобальный x
,
Это то, на что стоит обратить особое внимание, особенно при работе с наследованием:
struct Base
{
void AwesomeFunction() { }
};
struct Derived : public Base
{
// This definition 'hides' Base::AwesomeFunction
void AwesomeFunction() { }
};
Это сокрытие возможно только потому, что второе x
находится в меньшем объеме, чем глобальный x
,
Вы получаете ошибку redfinition для третьего x
потому что третий и второй x
находятся в той же области «уровень».
Используйте :: x для доступа к глобальной переменной из вашей программы. Прямо сейчас вы делаете локальную переменную и глобальную. Когда вы впервые печатаете x, он не может найти локальный, поэтому он предполагает, что вы имели в виду глобальный. После того, как вы сделаете свой локальный х, он больше не будет по умолчанию глобальным.
Что происходит в вашем коде, так это то, что локальная переменная имеет приоритет над глобальной переменной, если они принимают одно и то же имя. Вы можете использовать свою глобальную переменную в любом блоке в рамках программы, тогда как локальная переменная будет удалена в конце ее блока (основной). Однако компилятор не позволит вам объявить две локальные переменные с одинаковыми именами в одном блоке.
Объявления во внутренней области видимости (например, main) могут тень объявления во внешней области видимости (например, область видимости файла). Ваше третье объявление x находится в той же области действия, что и ваше второе, так что это ошибка повторного объявления.
Вы не переопределяете глобальную переменную; вы определяете отдельную локальную переменную с тем же именем.
C ++ позволяет вам повторно использовать имя для объявления чего-то другого в более узкой области, подобной этой; технически объявление во внутренней области видимости шкуры один во внешней области видимости, так что между объявлением и концом функции, x
ссылается на локальную переменную. Вы все еще можете получить доступ к глобальной переменной, указав ее в пространстве имен: ::x
,
Третье объявление будет пытаться повторно использовать имя в той же области, что недопустимо.