C++: static member functions and variables- redefinition of static variable?
-
08-07-2019 - |
Question
I was trying to incorporate the Singleton design pattern into my code, but I started getting a weird error:
main.obj : error LNK2005: "private: static class gameState * gameState::state" (?state@gameState@@0PAV1@A) already defined in gameState.obj
If you're not familiar with the singleton pattern, it is basically used to enforce only 1 instance of a certain object in the entire program. Here is the relevant code: gameState.h:
class gameState
{
public:
static gameState* Instance() {return state;}
.
.
.
private:
gameState();
static gameState* state;
};
gameState* gameState::state = new gameState();
and right now I'm just using the instance of that object in the main.cpp file:
gameState *currState = gameState::Instance();
.
.
.
for_each(currState->getHumanPieces().begin(),currState->getHumanPieces().end(), drawPieces);
It would seem I am trying to redefine gameState::state, but can't figure out why... help anyone?
that solved that, but one error still remains, which I didn't actually post before as I thought it was just part of the other one:
error LNK2019: unresolved external symbol "private: __thiscall gameState::gameState(void)" (??0gameState@@AAE@XZ) referenced in function "void __cdecl `dynamic initializer for 'private: static class gameState * gameState::state''(void)" (??__E?state@gameState@@0PAV1@A@@YAXXZ)
any good tip on how to fix that one as well?
Thanks both of you, its fixed :D
Solution
You need to put the definition of the static gameState*
into exactly one source file, i.e. this line:
gameState* gameState::state = new gameState();
If you put it in a header which is included by multiple source files, each has a definition of gameState::state
which leads to errors at link-time.
For the follow-up problem, use Vadakkumpadaths advice: you need to provide a definition for gameState
s constructor, not only a declaration.
OTHER TIPS
Add definition for your constructor to fix second linker error.
private:
gameState()
{
}
Use a header guard macro for the redefinition problem, and explicitly define your private constructor.