C++ статическая переменная bool
Я не могу понять то, что вызывает ошибки LNK2005, с которыми я столкнулся. Предположим, что у вас есть класс A:
Файл Ах:
#ifndef A_H
#define A_H
class A{
public:
static foo(void);
private:
static bool m_someVar;
};
bool A::m_someVar = false;
#endif
Файл A.cpp:
#include "A.h"
void A::foo(){
m_someVar = true;
}
Приведенный выше код вызывает LNK 2005, но следующий код этого не делает:
Файл Ах:
#ifndef A_H
#define A_H
class A{
public:
static foo(void);
private:
static bool m_someVar;
};
#endif
Файл A.cpp:
#include "A.h"
bool A::m_someVar = false;
void A::foo(){
m_someVar = true;
}
Может кто-нибудь объяснить, почему это происходит, хотя у меня есть охранники? Должен ли я также добавить #pragma один раз?
Заранее спасибо.
РЕДАКТИРОВАТЬ: вот ошибка компиляции: "ошибка LNK2005: " личное: статическое bool GameManager::m_isGameOver" (? M_isGameOver@GameManager@@0_NA) уже определено в Execution.obj"
2 ответа
include guards(и #ifndef, и #pragma) не работает в разных единицах компиляции, что является одной из причин, по которой вы никогда не должны определять что-либо в заголовочном файле, только объявлять их. За исключением шаблонов конечно.
Единица компиляции - это один.cpp-файл и все включенные заголовки. Каждый.cpp создает объектный файл, содержащий двоичное представление кода на средней стадии, это этап компиляции. Эти объектные файлы затем связываются вместе на этапе связывания. Поскольку каждый.cpp обрабатывается отдельно в C++, если у вас есть "float foo;" в header.hpp и в a.cpp и b.cpp есть header.hpp. Как компилятор узнает, что вы имеете в виду при запуске приложения?
"Статическая" переменная внутри объявления класса на самом деле является объявлением для внешней переменной, которая находится в области видимости этого класса. Как и любая переменная extern, она нуждается в определении ровно в одном исходном файле. В противном случае компоновщик будет жаловаться на это.
Вероятно, вы включаете файл.h из нескольких исходных файлов, поэтому у вас есть несколько определений.