SeedyROM
SeedyROM

Reputation: 2451

Clang linking error for C++ static class: undefined symbols

I have a static class that I'm using for my state driven game, upon compiling with XCODE I've been getting this linker error:

Undefined symbols for architecture x86_64:
  "Game::_gameState", referenced from:
      Game::Start() in Game.o
      Game::IsExiting() in Game.o
      Game::GameLoop() in Game.o
  "Game::_mainWindow", referenced from:
      Game::Start() in Game.o
      Game::GameLoop() in Game.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

My understanding of C++ is pretty limited, and I always find myself running into weird quirks whenever I try to use it. I'm not sure how I can define those symbols and keep it a static class. I tried to define them outside of the class definition with no luck, what am I doing wrong?

Here's the source:

Game.hpp

#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>

class Game
{
public:
    static void Start();

    static bool IsExiting();
    static void GameLoop();

    enum GameState { Uninitialized, ShowingSplash, 
               Paused, ShowingMenu, Playing, Exiting };

    static GameState _gameState;
    static sf::RenderWindow _mainWindow;
};

Game.cpp

#include "Game.hpp"

void Game::Start()
{
    if(_gameState != Uninitialized)
        return;

    _mainWindow.create(sf::VideoMode(1024, 768, 32), "This game!");
    _mainWindow.setVerticalSyncEnabled(true);
    _gameState = Playing;

    while(!IsExiting())
    {
        GameLoop();
    }

    _mainWindow.close();
}

bool Game::IsExiting()
{
    if(_gameState == Exiting)
        return true;
    else
        return false;
}

void Game::GameLoop()
{
    sf::Event currentEvent;
    while(_mainWindow.pollEvent(currentEvent))
    {
        switch(_gameState)
        {
            case Playing:
            {
                _mainWindow.clear(sf::Color::Black);
                _mainWindow.display();

                if(currentEvent.type == sf::Event::Closed)
                {
                    _gameState = Game::Exiting;
                }
                break;
            }
        }
    }
}

Upvotes: 0

Views: 1280

Answers (1)

johnsyweb
johnsyweb

Reputation: 141918

You need to define the static members outside the class declaration:

In Game.cpp:

Game::GameState Game::_gameState;
sf::RenderWindow Game::_mainWindow;

With all those public static methods, perhaps Game shouldn't be a class but a namespace.

Upvotes: 2

Related Questions