C ++ позволяет переопределение глобальной (const) переменной?

Я немного смущен глобальными константами. Насколько я понимаю (начальный уровень), «глобальные» переменные определяются вне блока и имеют область действия программы (источник: 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

2

Решение

#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:

  1. x в глобальной области видимости const double

  2. x в объеме main() типа double

Местный x скрывает глобальный x, Если вы хотите получить доступ к глобальной x внутри main(), вы можете сослаться на это как ::x,

    std::cout << "2) x=" << x << std::endl;
double x=3.5;  //uncommented

Нет, ты пытаешься представить другой названный объект x в сферу main(), Это невозможно, там уже есть один x в этой области, поэтому он терпит неудачу.

8

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

Второй x это не переопределение. это hiding глобальный x,
Это то, на что стоит обратить особое внимание, особенно при работе с наследованием:

  struct Base
{
void AwesomeFunction() { }
};

struct Derived : public Base
{
// This definition 'hides' Base::AwesomeFunction
void AwesomeFunction() { }
};

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

1

Используйте :: x для доступа к глобальной переменной из вашей программы. Прямо сейчас вы делаете локальную переменную и глобальную. Когда вы впервые печатаете x, он не может найти локальный, поэтому он предполагает, что вы имели в виду глобальный. После того, как вы сделаете свой локальный х, он больше не будет по умолчанию глобальным.

1

Что происходит в вашем коде, так это то, что локальная переменная имеет приоритет над глобальной переменной, если они принимают одно и то же имя. Вы можете использовать свою глобальную переменную в любом блоке в рамках программы, тогда как локальная переменная будет удалена в конце ее блока (основной). Однако компилятор не позволит вам объявить две локальные переменные с одинаковыми именами в одном блоке.

1

Объявления во внутренней области видимости (например, main) могут тень объявления во внешней области видимости (например, область видимости файла). Ваше третье объявление x находится в той же области действия, что и ваше второе, так что это ошибка повторного объявления.

1

Вы не переопределяете глобальную переменную; вы определяете отдельную локальную переменную с тем же именем.

C ++ позволяет вам повторно использовать имя для объявления чего-то другого в более узкой области, подобной этой; технически объявление во внутренней области видимости шкуры один во внешней области видимости, так что между объявлением и концом функции, x ссылается на локальную переменную. Вы все еще можете получить доступ к глобальной переменной, указав ее в пространстве имен: ::x,

Третье объявление будет пытаться повторно использовать имя в той же области, что недопустимо.

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