0

I have a state machine like code, which has state A,B and C, and a function changeState(char i) which can change the state of a system, and each state can call changeState(char i) to switch the system to another state:

struct State{
    State(char aName){
        this->name=aName;
    }
    char name;
};

void changeState(char i);

struct A : public State{
    A():State('A'){
        changeState('B');
    }
};

struct B : public State{
    B():State('B'){
        changeState('C');
    }
};

struct C : public State{
    C():State('C'){
    }
};

State* state;
void changeState(char i){
    switch(i){
        case 'A':
            state=new A();
            break;
        case 'B':
            state=new B();
            break;
        case 'C':
            state=new C();
            break;
    }
}

Now I want to trigger state change, start from A to C:

int main(){
    changeState('A');
    printf("%c\n",state->name);
    return 0;
}

the flow is : changeState('A')->new A()->changeState('B')->new B()->changeState(C)->new C(), I want the last state be C, but now is A, how can I modify changeState(char i) to do that? I try using a list to hold all temp state object:

std::list<State*> stateList;
void changeState(char i){
    switch(i){
        case 'A':
            stateList.push_front(new A());
            break;
        case 'B':
            stateList.push_front(new B());
            break;
        case 'C':
            stateList.push_front(new C());
            break;
    }
    stateList.pop_back();
}

int main(){
    stateList.push_front(new State('s'));
    changeState('A');
    printf("%lu %c\n",stateList.size(),stateList.back()->name);
    return 0;
}

but the last state is still A instead of C, how do I modify changeState(char i) ?

ggrr
  • 7,737
  • 5
  • 31
  • 53

1 Answers1

0

Lets break down the initial call using changeState('A') into the operations that happens:

  1. You call `changeState('A')
  2. You do new A()
  3. Which calls the A constructor which calls changeState('B')
  4. Which does new B()
  5. The B constructor calls changeState('C')
  6. Which does new C()
  7. And the new C object is assigned to the pointer state
  8. changeState returns, going back to the B constructor
  9. The B constructor returns, which puts control back in the changeState('B') call
  10. The assignment of state = new B() is performed
  11. The changeState function returns to the A constructor
  12. The A constructor returns to the changeState('A') call
  13. The state = new A() assignment is made
  14. The changeState function returns to the main function
  15. The state variable now points to an A object

The simplest solution? Don't call changeState in the constructors!


As for the other example with the list, remember that the list starts out empty. Then when you call changeState you add a node, then you immediately remove the same node you just added.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621