toestandspatroon C++

toestandspatroon C++

Het probleem is dat de compiler het bestand van boven naar beneden leest. Op de regel die

. bevat
game.state_ = &GameState::play;

hij weet nog steeds niet dat Playing erft van GameState . Het weet alleen dat Playing is een klasse die later zal worden gedeclareerd.

U moet de klassedeclaraties splitsen van methode-implementaties. Zorg dat eerst alle klassendeclaraties en later de methode-implementaties. In een groter project zou je ze allemaal opsplitsen in individuele *.h- en *.cpp-bestanden en deze volgorde zou natuurlijk gebeuren.

Verkort voorbeeld:

class Playing : public GameState
{
public:
    Playing();

    virtual void handleinput(Game& game, int arbitary);

    virtual void update(Game& game);
};

// Declarations of other classes...


Playing::Playing() {
    std::cout << "constructed Playing state" << std::endl;
}

void Playing::handleinput(Game& game, int arbitrary) {
    if (arbitary == 0)
        game.state_ = &GameState::intro;
    }
}

void Playing::update(Game& game) {
}

U kunt een deel van de methode binnen de klassendeclaratie laten. Meestal wordt het gedaan als de methode klein is, baat zou hebben bij inlining en dit soort circulaire afhankelijkheidsproblemen niet heeft.


Verplaats de implementaties van de functies out-of-line naar na de definities van alle klassen.

De compiler moet de overgeërfde klassen Playing . zien en Introduction volledig voordat het weet dat ze erven van GameState .

#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);

    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);

    virtual void update(Game& game) {}
};

void Introduction::handleinput(Game& game, int arbitary) 
{
    if (arbitary == 1)
        game.state_ = &GameState::play;
}

void Playing::handleinput(Game& game, int arbitary) 
{
    if (arbitary == 0)
        game.state_ = &GameState::intro;
}

Introduction GameState::intro;
Playing GameState::play;


int main(int argc, char const *argv[])
{
    Game thisgame;

    return 0;
}