2016-07-24 11 views
1

Ich mache eine Zustandsmaschine zum Umschalten von Spielzuständen (spielen-> Menü-> Setup) in meiner Spielengine, aber ich bekomme einen Segmentierungsfehler. Ich kann den Spielstatus vom oberen Level aus ändern, aber Wie kann ich den Spielstatus innerhalb eines Spielstatus ändern?Segmentierungsfehler beim Versuch, den Spielstatus zu ändern

Hier ist ein minimales Codebeispiel:

#include <iostream> 
#include <vector> 

class GameStateManager; 

class GameState { 
public: 
    GameState(GameStateManager* StateManager) { 
     StateManager = stateManager; 
    }; 

    virtual ~GameState(); 

    virtual void update() = 0; 

    GameStateManager* stateManager; 
}; 

class GameStateManager { 
public: 
    GameStateManager(); 
    ~GameStateManager(); 

    void changeGameState(GameState* state) { 
     if(!running) { 
      running = true; 
     } 

     // Cleanup the current state 
     if(!gameStates.empty()) { 
      for(unsigned int i = 0; i < gameStates.size(); i++) { 
       delete gameStates[i]; 
      } 
      gameStates.clear(); 

      std::cout << "Cleaning up GameState" << std::endl; 
     } 

     // Store and initialize the new game state 
     gameStates.push_back(state); 
    }; 

    void update() { 
     if(!gameStates.empty()) { 
      gameStates.back()->update(); 
     } 
    }; 

    std::vector<GameState*> gameStates; 
    bool running; 
}; 

class PlayState : public GameState { 
public: 
    PlayState(GameStateManager* stateManager) : GameState(stateManager) {}; 
    ~PlayState(); 

    void update() override { 
     // On some flag, initiate the next level 
     nextLevel(); 
    }; 

    void nextLevel() { 
     stateManager->changeGameState(new PlayState(stateManager)); 
    }; 
}; 

int main() { 
    GameStateManager stateManager; 

    stateManager.changeGameState(new PlayState(&stateManager)); 

    while(stateManager.running) { 
     for(unsigned int i = 0; i < 10000; i++) { 
      std::cout << "Round: " << i << std::endl; 

      // Segmentation fault here 
      stateManager.update(); 

      // This works 
      //stateManager.changeGameState(new PlayState(&stateManager)); 
     } 
     stateManager.running = false; 
    } 
    return 0; 
} 
+0

Wir wissen nicht, was 'gameStates' ist. Es scheint wie eine Warteschlange, aber ich kann nicht sagen, wie es implementiert ist. –

+0

gameStates ist ein Standard-std :: vector von GameState *. – lefti

Antwort

1

aus irgendeinem Grunde die stateManager nicht im GameState Konstruktor festgelegt werden.

so versuchen Sie dies:

class GameState { 
public: 
    GameState(GameStateManager* StateManager) : stateManager(StateManager) 
    { 
    }; 

    virtual ~GameState(); 

    virtual void update() = 0; 

    GameStateManager* stateManager; 
};