да, но вы объявляете это только один раз за единицу компиляции .
включайте охрану, убедитесь, что вы объявляете вещи только один раз для .cpp, который его использует.
Поэтому, если A.h
включено в B.h
, а impl.cpp
включает оба, тогда A.h
включается только в первый раз.
В вашем случае вы определяете значение макроса include guard какпеременная статического указателя.Таким образом, даже если impl.cpp
имеет его только один раз, impl2.cpp
, который включает в себя те же файлы, будет иметь их также, поэтому ваша статическая переменная будет иметь повторяющиеся определения во время компоновки
, если вы настаиваете на наличии статических переменных(как сказал Томас, это обычно плохой дизайн) лучше обернуть их в функцию;
myClass* getInstance() {
static myClass instance;
return &instance;
}
это немного лучше, потому что это гарантирует, что переменная действительно глобальная, в некоторых архитектурах (например, Дарвин)иметь, что static
переменные уникальны для динамической библиотеки, а не для процесса, так что это может привести к запутанному поведению / переносимости
Кроме того, и, что более важно, статическая инициализация всегда происходит перед main, и порядок не гарантируется,Со статическими переменными функции переменные инициализируются «по требованию», поэтому на них не влияют проблемы с порядком инициализации
для инициализации глобального указателя:
myClass** getGlobalRef() {
static myClass* val;
return &val;
}
//and you set it at run-time, avoiding static-initialization happening before main
* getGlobalRef() = new myClass();