Вопрос по namespaces, static, c++ – статические и нестатические переменные в пространстве имен

34

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

foo.h:

namespace foo {
    int bar;
}

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

Почему это работает? И что более важно, почемуdoesn't это работаетwithout static? Что значитstatic значит, когда используется вnamespace?

Ваш Ответ

4   ответа
36

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

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

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

0

Также обратите внимание, чтоconst int в пространстве имен (глобальная) область в C ++ имеетstatic неявно добавлено по умолчанию:Определите постоянные переменные в заголовке C ++

Чтобы лучше понять, что происходит, сделайтеreadelf на промежуточных объектных файлах ELF компиляции, и вы увидите, ясно, символы определены дважды или нет. Вот подробный пример:Что значит "статичный" значит в С?

24

Когда вы объявляете переменную какstatic, это означает, что егоscope is limited to the given translation unit только. Безstatic сфера является глобальной.

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

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

4

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

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

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

Похожие вопросы