У меня есть конечный автомат, такой как код, который имеет состояния 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 , но теперь это, как я могу изменить 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)?
Давайте разберем исходный вызов, используя changeState('A')
в операции, которые происходят:
new A()
A
конструктор, который вызывает changeState('B')
new B()
B
вызов конструктора changeState('C')
new C()
C
объект назначен указателю state
changeState
возвращается, возвращаясь к B
конструкторB
конструктор возвращает, что возвращает контроль в changeState('B')
вызовstate = new B()
выполняетсяchangeState
функция возвращает к A
конструкторA
конструктор возвращается к changeState('A')
вызовstate = new A()
назначение сделаноchangeState
функция возвращает к main
функцияstate
переменная теперь указывает на A
объектСамое простое решение? Не звони changeState
в конструкторах!
Что касается другого примера со списком, помните, что список начинается пустым. Затем, когда вы звоните changeState
Вы добавляете узел, а затем немедленно удаляете тот же самый узел, который только что добавили.
Других решений пока нет …