Question

This is my first question on StackExchange, so please let me know if there's more information needed. I'll try to be as complete and concise as possible. The code is included below.

I'm trying to implement the state manager found here:Managing Game States in C++

I've downloaded the code and copied it virtually word for word (I changed a couple of class and variable names). The code compiles until I add the following line in main.cpp:

game.ChangeState(PlayState::Instance());

Which results in the following linker error:

error LNK2001: unresolved external symbol "private: static class PlayState PlayState::m_Instance" (?m_Instance@PlayState@@0V1@A)

main.cpp

#include "JewelEngine.h"
#include "PlayState.h"

int main(int argc, const char* argv[])
{
    JewelEngine game;
    game.Init();

    game.ChangeState(PlayState::Instance());

    while(game.Running())
    {
        game.HandleEvents();
        game.Update();
        game.Render();
    }
    game.Cleanup();
    return 0;
}

PlayState.h

#ifndef PLAYSTATE_H
#define PLAYSTATE_H

#include "GameState.h"

class PlayState:public GameState
{
public:
    void Init();
    void Cleanup();

    void HandleEvents(JewelEngine* game);
    void Update(JewelEngine* game);
    void Render(JewelEngine* game);

    void Pause();
    void Resume();

    static PlayState* Instance()
    {
        return &m_Instance;
    }

protected:
    PlayState() { }

private:
    static PlayState m_Instance;

};

#endif

GameState.h

#ifndef GAMESTATE_H
#define GAMESTATE_H

#include "JewelEngine.h"

class GameState
{
public:
    virtual void Init() = 0;
    virtual void Cleanup() = 0;

    virtual void HandleEvents(JewelEngine* game) = 0;
    virtual void Update(JewelEngine* game) = 0;
    virtual void Render(JewelEngine* game) = 0;

    virtual void Pause() = 0;
    virtual void Resume() = 0;

    void ChangeState(JewelEngine* game, GameState* state)
    {
        game->ChangeState(state);
    }

protected:
    GameState();
};

#endif

I've tried removing the static member and function, making the constructor public, and instead declaring the PlayState object in main, then passing it's address into the ChangeState function, but a very similar linking error still happens. I've been hopelessly stuck on this problem for 2 days and would greatly appreciate any help offered. Thank you.

Was it helpful?

Solution

You've declared the static variable m_Instance, but you need to define it.

Add

PlayState PlayState::m_Instance = PlayState(); // static variable definition follows the syntax:
                                               // (type) (var name) = (default assignment);

in your PlayState.cpp file

You technically don't need the PlayState() call here, since the constructor would be called automatically. Just added it for completion. The key take away is static variables need to be defined in their translation unit. A declaration within a class/struct won't suffice since you need to "create" them.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top