Finite State Machine in C++ I made a state machine.

You can press 0 and 1 to switch between the hypothetical menu and playing state.

I hope you can help me improve it further.

StateManager.h

#pragma once

#ifndef StateManager_H
#define StateManager_H

#include &lt;iostream&gt;
#include "State.h"

/*
State classes
*/

class StateManager {
public:
    // Define m_current_state upon the creation of this class (since that prevents there being a nullptr error in change_state
    StateManager(State* state)
        : m_current_state(state)
    {}

    void change_state(State* state) {
        m_current_state-&gt;on_exit();
        m_current_state = state;
        m_current_state-&gt;on_enter();
    }

    void update_state(StateManager* manager) {
        m_current_state-&gt;on_update(manager);
    }

    State* get_state() {
        return m_current_state;
    }

private:
    State* m_current_state;
};

#endif


State.h

#pragma once

#ifndef State_H
#define State_H

#include "StateManager.h"

// I'm using forward declaration here since I've had a problem with circular dependency
class StateManager;

class State {
public:
    // All states have to have these three functions
    virtual void on_enter() = 0;
    virtual void on_update(StateManager* state_manager) = 0;
    virtual void on_exit() = 0;
};

#endif


IntroState.h

#pragma once

#ifndef IntroState_H
#define IntroState_H

#include "StateManager.h"
#include "State.h"
#include "GameState.h"

/*
Basic test state for demonstration
*/

class MenuState : public State {
public:
    MenuState();

    virtual void on_enter() override;

    virtual void on_update(StateManager* state_manager) override;

    virtual void on_exit() override;

private:
    bool should_change_state;
};

#endif


Introstate.cpp

#include "IntroState.h"

MenuState::MenuState()
    : should_change_state(false)
{}

void MenuState::on_enter(){
    std::cout &lt;&lt; "Entering the menu state" &lt;&lt; std::endl;
}

void MenuState::on_update(StateManager* state_manager){
    // update the menu
    std::cout &lt;&lt; "Should the state be changed to the playing state" &lt;&lt; std::endl;
    std::cin &gt;&gt; should_change_state;
    if (should_change_state == true) {
        state_manager-&gt;change_state(new PlayingState());
    }
}

void MenuState::on_exit(){
    std::cout &lt;&lt; "Exiting the menu state" &lt;&lt; std::endl;
}


GameState.h

#pragma once

#ifndef GameState_H
#define GameState_H

#include "IntroState.h"
#include "State.h"

/*
Basic test state for demonstration
*/

class PlayingState : public State {
public:
    PlayingState();

    virtual void on_enter() override;

    virtual void on_update(StateManager* state_manager) override;

    virtual void on_exit() override;

private:
    bool should_change_state;
};

#endif


GameState.cpp

#include "GameState.h"

PlayingState::PlayingState()
    : should_change_state(false)
{}

void PlayingState::on_enter() {
    std::cout &lt;&lt; "Entering the playing state" &lt;&lt; std::endl;
}

void PlayingState::on_update(StateManager* state_manager) {
    // update the menu
    std::cout &lt;&lt; "Should the state be changed to the menu state" &lt;&lt; std::endl;
    std::cin &gt;&gt; should_change_state;
    if (should_change_state == true) {
        state_manager-&gt;change_state(new MenuState());
    }
}

void PlayingState::on_exit() {
    std::cout &lt;&lt; "Exiting the playing state" &lt;&lt; std::endl;
}


Source.cpp

#include "StateManager.h"
#include "State.h"
#include "IntroState.h"

int main() {
    StateManager* manager = new StateManager(new MenuState());

    int exit = 0;
    while (exit != 1) {
        manager-&gt;update_state(manager);
    }

    return 0;
}


Thanks!
Last things first

Before I forget about it (because it's peripheral in your code), I'll point out the new StateManager(new MenuState());, which is among the don't of C++. Raw pointers are dangerous! if you don't delete the allocated memory afterwards, you'll leave a leak (and you didn't). So use smart pointers (std::unique_ptr or std::shared_ptr) instead. That's quite an interesting topic, but you'll have to study it for yourself. Or better still, allocate your objects on the stack (State_manager manager;)

The design


  manager-&gt;update_state(manager); 


is a bit weird, don't you think? What would it mean to write manager-&gt;update_state(other_manager)? Probably not much. So you could rewrite the update_state method like this:

void update_state() {
    m_current_state-&gt;on_update(this); // instead of current-&gt;on_update(removed_argument)
}


It's cleaner and completely equivalent. But then you have to write such things as:


while (exit != 1) {
    manager-&gt;update_state();
}



It isn't obvious. Where are the external input taken from? Following the thread, I see that the the state itself is responsible for managing the transition: it will ask user input and control if changing from the current state (i.e itself) to the next state (that it will have to determine too) is feasible. Without saying if it is a good design or not, I wonder whether it is useful in anyway to have a state manager at all. Its only role seems to call on_enter and on_exit, but baking that into the State class isn't difficult since on_enter and on_exit are part of its interface (or you could even dispense with it; just add instructions at the beginning and the end of the update function). It also keeps track of the current state, but a simple current_state variable would do the trick:

std::unique_ptr&lt;State&gt; current_state = std::make_unique&lt;Intro_state&gt;();
while (exit != 1) current_state-&gt;update();


But then you might also wonder why this exit is outside of the state machine. If there is an intro-state, a game-state


  At that point I want to take a break and tell you that naming your file with a synonym or a paraphrases for the class it contains is a really bad idea. The Game_state class should be in Game_state.h, not in gaming_state.h, that doesn't make any sense.


then why isn't there an exit-state? It could do some clean-up, display credits, I don't know. So now we have:

std::unique_ptr&lt;State&gt; current_state = std::make_unique&lt;Intro_state&gt;();
current_state-&gt;update();


But then the current_state variable itself, and the allocation that goes along with it, are also superfluous. Intro_state().update(); would look weird, but what about intro();? So we have a function void intro() that asks if it needs to call void game() or void exit(), and a void game() that asks if it needs to call void intro() again or void exit(). The design pattern has disappeared, and yet we haven't removed any functionality or usability feature, only simplified. From that observation I feel I can conclude safely that there is a problem in your design.

My 3 cents

Many C++ manuals insist on the object-oriented part of the language and the so-called design patterns. It isn't, IMHO (which, that said, isn't really my own but one taken by most of the prominent figures of the C++ scene), a good way to learn C++. Try rather to explore the robustness of the language or its versatility.