Статические и нестатические переменные в пространстве имен
У меня есть пространство имен foo
, которое содержит целое число bar
, объявленное так...
foo.h:
namespace foo {
int bar;
}
Теперь, если я включаю foo.h
только в один файл, это работает отлично. Но проблема возникает, когда я включаю foo.h
из двух или более файлов: я получаю ошибку компоновщика. Я понял, что если я объявляю bar
как static
, я могу включить foo.h
в несколько файлов. Это кажется мне странным, потому что я не знал, что можно объявить статическую переменную внутри пространства имен. (что это значит?)
Почему это работает? И что еще более важно, почему не работает без static
? Что означает static
при использовании в namespace
?
Ответы
Ответ 1
В <контекстах > static
имеется несколько значений. В этом конкретном контексте это означает, что переменная имеет внутреннюю связь, и поэтому каждая единица перевода, которая включает этот заголовок, будет иметь свою собственную копию переменной.
Обратите внимание, что в то время как это отключит ошибку компоновщика, она будет поддерживать отдельную переменную foo::bar
для каждого из созданных объектных файлов (изменения не будут отображаться в разных объектных файлах).
Если вам нужна одна переменная, вы должны объявить ее как extern
в заголовке и предоставить одно определение в одной единицы перевода.
Ответ 2
Когда вы объявляете переменную как static
, это означает, что ее область ограничена только указанной единицей перевода. Без static
область действия глобальна.
Когда вы объявляете переменную как static
внутри .h файла (внутри или без namespace
; не имеет значения) и включаете этот заголовочный файл в различные .cpp файлы, переменная static
становится локальной областью к каждому из файлов .cpp
.
Итак, теперь каждый .cpp файл, содержащий этот заголовок, будет иметь свою собственную копию этой переменной.
Без ключевого слова static
компилятор будет генерировать только одну копию этой переменной, поэтому, как только вы включите заголовочный файл в нескольких файлах .cpp, компоновщик будет жаловаться на несколько определений.
Ответ 3
Проблема вызвана наличием нескольких определений переменной. Определения в разных единицах перевода конфликтуют друг с другом, так же как множественные определения не встроенных функций не будут работать.
Когда вы делаете переменную static, вы предоставляете переменную внутреннюю привязку, поэтому каждая единица перевода имеет свою собственную независимую копию.
То, что вы, вероятно, действительно хотите, это поместить только объявление в заголовок (используя extern), а затем поместить определение в файл реализации.