Я не могу понять то, что вызывает ошибки LNK2005, с которыми я столкнулся.
Предположим, что у вас есть класс A:
Файл A.h:
#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, а следующий код — нет.
Файл A.h:
#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:» private: static bool GameManager :: m_isGameOver «(? m_isGameOver @ GameManager @@ 0_NA) уже определен в Execution.obj»
include guards (как #ifndef, так и #pragma) не работает в разных единицах компиляции, что является одной из причин, по которой вам никогда не следует ничего определять в заголовочном файле, только объявляйте их. За исключением шаблонов конечно.
Единица компиляции — это один .cpp-файл и все включенные заголовки. Каждый .cpp создает объектный файл, содержащий двоичное представление кода на средней стадии, это этап компиляции. Эти объектные файлы затем связываются вместе на этапе связывания. Поскольку каждый .cpp обрабатывается отдельно в C ++, если у вас есть «float foo;» в header.hpp и в a.cpp и b.cpp есть header.hpp, как компилятор узнает, какой foo вы имеете в виду при запуске приложения?
«Статическая» переменная внутри объявления класса на самом деле является объявлением для внешней переменной, которая находится в области видимости этого класса. Как и любая переменная extern, необходимо определить в точно один исходный файл. В противном случае компоновщик будет жаловаться на это.
Вероятно, вы включаете файл .h из нескольких исходных файлов, поэтому у вас есть несколько определений.