Это мой первый вопрос о StackExchange, поэтому, пожалуйста, дайте мне знать, если вам нужно больше информации. Я постараюсь быть максимально полным и лаконичным. Код включен ниже.
Я пытаюсь реализовать государственный менеджер, найденный здесь:Управление игровыми состояниями в C ++
Я скачал код и скопировал его практически дословно (я изменил пару имен классов и переменных). Код компилируется, пока я не добавлю следующую строку в main.cpp:
game.ChangeState(PlayState::Instance());
Что приводит к следующей ошибке компоновщика:
ошибка LNK2001: неразрешенный внешний символ «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
Я попытался удалить статический член и функцию, сделать конструктор общедоступным и вместо этого объявить объект PlayState в main, а затем передать его адрес в функцию ChangeState, но очень похожая ошибка компоновки все равно происходит. Я безнадежно застрял на этой проблеме в течение 2 дней и был бы очень признателен за любую предложенную помощь. Спасибо.
Вы объявили статическую переменную m_Instance, но вам нужно определить ее.
добавлять
PlayState PlayState::m_Instance = PlayState(); // static variable definition follows the syntax:
// (type) (var name) = (default assignment);
в вашем файле PlayState.cpp
Технически вам здесь не нужен вызов PlayState (), поскольку конструктор будет вызываться автоматически. Просто добавил это для завершения. Ключевым моментом является то, что статические переменные должны быть определены в их единице перевода.
Объявление внутри класса / структуры будет недостаточным, так как вам нужно «создать» их.
Других решений пока нет …