首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++中分层状态机的实现问题

C++中分层状态机的实现问题
EN

Stack Overflow用户
提问于 2022-07-31 12:27:54
回答 2查看 69关注 1票数 1

我一直试图在C++中实现分层状态机。我选择了基于状态设计模式和复合设计模式的方法。根据复合设计模式,我为原子状态(简单状态)和复合状态(由状态机组成的状态)定义了一个公共抽象基类。

State.h

代码语言:javascript
复制
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

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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;}
    
};

然后,我定义了顶级状态机。

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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()

  • Invoking Ready::update()

  • Invoking state_machine.update()

中的

问题显然出现在以下语句中:从parent->switchState(& static_cast<StateMachine*>(parent)->cat)调用的Ready::update()

不幸的是我不明白为什么。有人能帮我理解我做错了什么吗?提前谢谢。

编辑:

继承的子对象StateCompositeStateMachine对象中的内容:

EN

回答 2

Stack Overflow用户

发布于 2022-07-31 15:52:38

程序崩溃的原因是没有初始化active复合状态中的Cat成员。

票数 0
EN

Stack Overflow用户

发布于 2022-07-31 15:53:11

有一种替代方法,用于设备驱动程序中的中断处理程序。使用逻辑堆叠的指针结束操作函数,以便在每个中断结束时执行操作。这样做的一个优点是,如果需要在某个级别添加一个额外的步骤,那么它只是在该级别上为该步骤使用另一个函数。我记得一个驱动程序在一个switch case语句中有超过200种情况来处理这个问题,它通过切换到3个逻辑级别的结束操作处理程序来简化。

代码语言:javascript
复制
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;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73183304

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档