Я пытаюсь спровоцировать простой шаблон State, после выполнения некоторых из прекрасных учебников здесь: http://gameprogrammingpatterns.com/state.htmlсостояния шаблон C++
Я на полпути через этот текущий учебник, и я пытаюсь повторить статические экземпляры каждое состояние, содержащее их в базовом классе. Однако, когда дело доходит до состояний переключения, g ++ выбрасывает эту ошибку.
state_test.cpp: In member function ‘virtual void Introduction::handleinput(Game&, int)’:
state_test.cpp:55:16: error: cannot convert ‘Playing*’ to ‘GameState*’ in assignment
game.state_ = &GameState::play;
^
Теперь я понимаю, что ошибка включает преобразование указателя, но я действительно изо всех сил, чтобы увидеть, как это исправить. Поскольку я следовал этому парному коду, я как бы ожидал, что он сработает, но поскольку он меняет его, когда он продвигается вперед и пытается укрепить лучшую практику, у меня нет его полного исходного кода. Тем не менее, я считаю, что для меня важно понять код на этом этапе, прежде чем я перехожу к остальной части учебника.
Ниже приведен код, который я создал, пытаясь повторить свою государственную систему:
#include <iostream>
class Game;
class Introduction;
class Playing;
class GameState
{
public:
static Introduction intro;
static Playing play;
virtual ~GameState() {std::cout << "an undefined GameState has been destroyed" << std::endl;}
virtual void handleinput(Game& game, int arbitary) {}
virtual void update(Game& game) {}
};
class Game
{
public:
Game()
{}
~Game()
{}
virtual void handleinput(int arbitary)
{
state_->handleinput(*this, arbitary);
}
virtual void update()
{
state_->update(*this);
}
//private:
GameState* state_;
};
class Introduction : public GameState
{
public:
Introduction()
{
std::cout << "constructed Introduction state" << std::endl;
}
virtual void handleinput(Game& game, int arbitary)
{
if (arbitary == 1)
game.state_ = &GameState::play;
}
virtual void update(Game& game) {}
};
class Playing : public GameState
{
public:
Playing() {std::cout << "constructed Playing state" << std::endl;}
virtual void handleinput(Game& game, int arbitary)
{
if (arbitary == 0)
game.state_ = &GameState::intro;
}
virtual void update(Game& game) {}
};
int main(int argc, char const *argv[])
{
Game thisgame;
return 0;
}
Любые идеи, почему моя реализация не компиляцией?
EDIT:
Таким образом, в ответ на ранее обучающимся, за что я был очень благодарен, я пересмотрел код. Начну с того, что все это было в отдельных файлах, но это было больше проблем, чем для такого небольшого количества тестового кода. Я просто переписал один заголовочный файл, который объявил классы, а затем определил их в файле .cpp.
Вот .h файл:
class Introduction;
class Playing;
class Game;
class GameState;
class GameState
{
public:
static Introduction intro;
static Playing play;
virtual ~GameState();
virtual void handleinput(Game& game, int arbitary);
virtual void update(Game& game);
};
class Introduction : public GameState
{
public:
Introduction();
virtual void handleinput(Game& game, int arbitary);
virtual void update(Game& game);
};
class Playing : public GameState
{
public:
Playing();
virtual void handleinput(Game& game, int arbitary);
virtual void update(Game& game);
};
class Game
{
public:
Game();
~Game();
virtual void handleinput(int arbitary);
virtual void update();
GameState* state_;
};
А вот файл .cpp:
#include <iostream>
#include "state.h"
GameState::~GameState()
{std::cout << "Exiting Game State Instance" << std::endl;}
void GameState::handleinput(Game& game, int arbitary)
{}
void GameState::update(Game& game)
{}
Game::Game()
{}
Game::~Game()
{}
void Game::handleinput(int arbitary)
{
state_->handleinput(*this, arbitary);
}
void Game::update()
{
state_->update(*this);
}
Introduction::Introduction()
{
std::cout << "constructed Introduction state" << std::endl;
}
void Introduction::handleinput(Game& game, int arbitary)
{
if (arbitary == 1)
game.state_ = &GameState::play;
}
void Introduction::update(Game& game) {}
Playing::Playing()
{
std::cout << "constructed Playing state" << std::endl;
}
void Playing::handleinput(Game& game, int arbitary)
{
if (arbitary == 0)
game.state_ = &GameState::intro;
}
void Playing::update(Game& game) {}
int main(int argc, char const *argv[])
{
Game mygame;
return 0;
}
И я до сих пор не могу заставить его работать. Предыдущая ошибка исчезла, но я изо всех сил пытаюсь получить доступ к статическим экземплярам «введения» и играть внутри базового класса. Произошла ошибка:
/tmp/ccH87ioX.o: In function `Introduction::handleinput(Game&, int)':
state_test.cpp:(.text+0x1a9): undefined reference to `GameState::play'
/tmp/ccH87ioX.o: In function `Playing::handleinput(Game&, int)':
state_test.cpp:(.text+0x23f): undefined reference to `GameState::intro'
collect2: error: ld returned 1 exit status
Я думал, что у меня это было! Так расстроено!
Я должен добавить, что ответ, предоставленный RustyX, компилируется, однако мне нужно переместить экземпляры «воспроизведения» и «введения» вне определения класса, и тогда я не могу ставить их статически, I что это важно, потому что мне нужен только один экземпляр каждого, и я хотел бы, чтобы они были инициализированы как можно раньше.
Возможно, вас заинтересует структура [STTCL] (https://github.com/makulik/sttcl). –