当状态机中存在递归状态更改时,如何保持上次创建的状态?

时间:2015-11-30 08:18:06

标签: c++ state-machine

我有一个像代码一样的状态机,它有状态A,B和C,以及一个可以改变系统状态的函数changeState(char i),每个状态都可以调用changeState(char i)来切换系统到另一个州:

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

现在我想触发状态更改,从A开始到C:

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

流程是:changeState('A') - > new A() - > changeState('B') - > new B() - > changeState(C) - > new C() ,我希望最后一个状态为C,但现在是A,如何修改changeState(char i)来做到这一点?我尝试使用列表来保存所有临时状态对象:

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

但是最后一个状态仍然是A而不是C,我该如何修改changeState(char i)?

1 个答案:

答案 0 :(得分:0)

让我们使用changeState('A')将初始调用分解为发生的操作:

  1. 您调用`changeState(&#39; A&#39;)
  2. 你做new A()
  3. 调用调用A
  4. changeState('B')构造函数
  5. new B()
  6. B构造函数调用changeState('C')
  7. new C()
  8. 并将新的C对象分配给指针state
  9. changeState返回,返回B构造函数
  10. B构造函数返回,将控件重新置于changeState('B')调用
  11. 执行state = new B()的分配
  12. changeState函数返回A构造函数
  13. A构造函数返回changeState('A')调用
  14. state = new A()分配
  15. changeState函数返回main函数
  16. state变量现在指向A对象
  17. 最简单的解决方案?不要在构造函数中调用changeState

    至于列表的另一个示例,请记住列表开始为空。然后当您调用changeState添加节点时,您会立即删除刚添加的同一节点。