我一直试图在C++中实现分层状态机。我选择了基于状态设计模式和复合设计模式的方法。根据复合设计模式,我为原子状态(简单状态)和复合状态(由状态机组成的状态)定义了一个公共抽象基类。
State.h
class State {
public:
virtual void notifyCatenaryModeRequested(bool state) = 0;
virtual void notifyBatteryModeRequested(bool state) = 0;
virtual void notifyMainContactorsCloseRequested(bool state) = 0;
virtual void update() = 0;
};StateAtomic.h
#include "State.h"
#include "StateComposite.h"
class StateAtomic : public State {
public:
StateAtomic(StateComposite* parent) : parent(parent) {}
void notifyCatenaryModeRequested(bool state) {cat_mode_requested = state;}
void notifyBatteryModeRequested(bool state) {bat_mode_requested = state;}
void notifyMainContactorsCloseRequested(bool state) {main_contactors_close_requested = state;}
virtual void update() = 0;
protected:
StateComposite *parent;
bool cat_mode_requested;
bool bat_mode_requested;
bool main_contactors_close_requested;
};StateComposite.h
#include "State.h"
class StateComposite : public State {
public:
StateComposite(StateComposite* parent) : parent(parent) {}
void notifyCatenaryModeRequested(bool state) {active->notifyCatenaryModeRequested(state);}
void notifyBatteryModeRequested(bool state) {active->notifyBatteryModeRequested(state);}
void notifyMainContactorsCloseRequested(bool state) {main_contactors_close_requested = state;}
void update() {active->update();}
void switchState(State * new_state) {active = new_state;}
protected:
StateComposite* parent;
State* active;
};根据状态设计模式,我为状态机的各个状态定义了一个类。
Ready.h
#include "StateAtomic.h"
class StateMachine;
class Ready : public StateAtomic {
public:
Ready(StateMachine *parent) : StateAtomic(parent) {}
void update() {
std::cout << "Ready" << std::endl;
if (cat_mode_requested && main_contactors_close_requested) {
parent->switchState(& static_cast<StateMachine*>(parent)->cat);
std::cout << "Switch to cat." << std::endl;
} else if (bat_mode_requested && main_contactors_close_requested) {
parent->switchState(& static_cast<StateMachine*>(parent)->bat);
std::cout << "Switch to bat." << std::endl;
}
}
};Cat.h
#include "StateComposite.h"
#include "CatPrecharge.h"
#include <iostream>
class StateMachine;
class Cat : public StateComposite {
public:
Cat(StateMachine *parent) : StateComposite(parent) {}
void update() {std::cout << "Cat" << std::endl;}
};然后,我定义了顶级状态机。
#include "StateComposite.h"
#include "StateAtomic.h"
#include "Ready.h"
#include "Cat.h"
#include <iostream>
class StateMachine : public StateComposite {
public:
StateMachine() : StateComposite(nullptr), ready(this), cat(this) {
active = &ready;
}
void update() {active->update();}
private:
Ready ready;
Cat cat;
friend class Ready;
friend class Cat;
};一个非常简单的应用程序
main.cpp
#include "StateMachine.h"
#include <cstdlib>
using namespace std;
struct command {
bool cat_mode_requested;
bool bat_mode_requested;
bool main_contactors_close_requested;
};
int main(int argc, char** argv) {
StateMachine state_machine;
command active_command;
for (uint8_t i = 0; i < 3; i++) {
std::cout << "Cat mode requested?" << std::endl;
std::cin >> active_command.cat_mode_requested;
std::cout << "Bat mode requested?" << std::endl;
std::cin >> active_command.bat_mode_requested;
std::cout << "Main contactors close requested?" << std::endl;
std::cin >> active_command.main_contactors_close_requested;
state_machine.notifyCatenaryModeRequested(active_command.cat_mode_requested);
state_machine.notifyBatteryModeRequested(active_command.bat_mode_requested);
state_machine.notifyMainContactorsCloseRequested(active_command.main_contactors_close_requested);
state_machine.update();
}
}我发现以下步骤会导致程序崩溃:
调用state_machine.update()
Ready::update()
state_machine.update()中的
问题显然出现在以下语句中:从parent->switchState(& static_cast<StateMachine*>(parent)->cat)调用的Ready::update()。
不幸的是我不明白为什么。有人能帮我理解我做错了什么吗?提前谢谢。
编辑:
继承的子对象StateComposite在StateMachine对象中的内容:

发布于 2022-07-31 15:52:38
程序崩溃的原因是没有初始化active复合状态中的Cat成员。
发布于 2022-07-31 15:53:11
有一种替代方法,用于设备驱动程序中的中断处理程序。使用逻辑堆叠的指针结束操作函数,以便在每个中断结束时执行操作。这样做的一个优点是,如果需要在某个级别添加一个额外的步骤,那么它只是在该级别上为该步骤使用另一个函数。我记得一个驱动程序在一个switch case语句中有超过200种情况来处理这个问题,它通过切换到3个逻辑级别的结束操作处理程序来简化。
typedef void (*PTRFUN)() // pointer to function
void fun_driver()
{
PTRFUN pflvl0 = fun_lvl00; // what to do at next level 0
PTRFUN pllvl1 = fun_lvl10; // what to do at next level 1
// ... // start some operation
return;
}
void fun_int() // interrupt function
{
// ...
pflvl1(); // call lvl1 handler
return;
}
void fun_lvl10()
{
pflvl1 = fun_lvl11; // next interrupt goes to lvl11
// ...
return;
}
void fun_lvl11()
{
pflvl1 = fun_lvl10; // reset back to lvl10
pflvl0(); // call higher level
return;
}
void fun_lvl00()
{
// ... // set a completion status
// ... // so OS handles end of operation action
return;
}https://stackoverflow.com/questions/73183304
复制相似问题