Подтвердить что ты не робот

Статические и нестатические переменные в пространстве имен

У меня есть пространство имен foo, которое содержит целое число bar, объявленное так...

foo.h:

namespace foo {
    int bar;
}

Теперь, если я включаю foo.h только в один файл, это работает отлично. Но проблема возникает, когда я включаю foo.h из двух или более файлов: я получаю ошибку компоновщика. Я понял, что если я объявляю bar как static, я могу включить foo.h в несколько файлов. Это кажется мне странным, потому что я не знал, что можно объявить статическую переменную внутри пространства имен. (что это значит?)

Почему это работает? И что еще более важно, почему не работает без static? Что означает static при использовании в namespace?

4b9b3361

Ответ 1

В <контекстах > static имеется несколько значений. В этом конкретном контексте это означает, что переменная имеет внутреннюю связь, и поэтому каждая единица перевода, которая включает этот заголовок, будет иметь свою собственную копию переменной.

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

Если вам нужна одна переменная, вы должны объявить ее как extern в заголовке и предоставить одно определение в одной единицы перевода.

Ответ 2

Когда вы объявляете переменную как static, это означает, что ее область ограничена только указанной единицей перевода. Без static область действия глобальна.

Когда вы объявляете переменную как static внутри .h файла (внутри или без namespace; не имеет значения) и включаете этот заголовочный файл в различные .cpp файлы, переменная static становится локальной областью к каждому из файлов .cpp.
Итак, теперь каждый .cpp файл, содержащий этот заголовок, будет иметь свою собственную копию этой переменной.

Без ключевого слова static компилятор будет генерировать только одну копию этой переменной, поэтому, как только вы включите заголовочный файл в нескольких файлах .cpp, компоновщик будет жаловаться на несколько определений.

Ответ 3

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

Когда вы делаете переменную static, вы предоставляете переменную внутреннюю привязку, поэтому каждая единица перевода имеет свою собственную независимую копию.

То, что вы, вероятно, действительно хотите, это поместить только объявление в заголовок (используя extern), а затем поместить определение в файл реализации.