C++ 在C+中实现状态机+;用于嵌入式系统

C++ 在C+中实现状态机+;用于嵌入式系统,c++,oop,switch-statement,embedded,motion,C++,Oop,Switch Statement,Embedded,Motion,我正在设计一个简单的电机控制器,它可以处于(至少)4种状态-怠速-加速-最大速度-减速 我认为尝试实现某种状态机是最好的方法。目前,使用switch语句似乎是一个很好的解决方案,因为它很简单,可以让我将所有“运动内容”保存在一个对象中(我们称之为Move) 这似乎合理吗?有谁能建议一个更合适的方法吗? 我知道有些人喜欢将每个状态分割成它的对象,但是有几个人告诉我在为MCU编写时要避免继承。我不会在这里使用继承,不是因为MCU,而是因为继承意味着抽象,对4个状态的抽象不值得(当然,也有例外) 您必

我正在设计一个简单的电机控制器,它可以处于(至少)4种状态-怠速-加速-最大速度-减速

我认为尝试实现某种状态机是最好的方法。目前,使用switch语句似乎是一个很好的解决方案,因为它很简单,可以让我将所有“运动内容”保存在一个对象中(我们称之为Move)

这似乎合理吗?有谁能建议一个更合适的方法吗?
我知道有些人喜欢将每个状态分割成它的对象,但是有几个人告诉我在为MCU编写时要避免继承。

我不会在这里使用继承,不是因为MCU,而是因为继承意味着抽象,对4个状态的抽象不值得(当然,也有例外)

您必须决定是否要分离状态上下文。如果没有,则将其保存在一个类中。如果最终得到许多方法和属性,那么应该将其拆分

如果需要拆分,请使用状态模式,或者如果没有很多状态,请保持简单:

为每个状态定义一个类。此类表示状态行为。不要忘记使用构造函数作为输入点,使用析构函数作为离开点

然后定义一个FSM类在状态之间切换。FSM应该包含一个循环,该循环创建当前状态、运行当前状态、检查其状态,并在需要时销毁当前状态并创建下一个状态

例如:

// Idle
class Idle {
public:
    Idle() {
        // entry point
    }
    ~Idle() {
        // leaving point
    }
    void step() {
        // actual work
    }
    // some getters to examine state
private:
    // helper methods
    // state attributes (context)
};

class FSM {
public:
    void run() {
        State current(sIdle);
        while (current != sExit) {
            switch (current) {
                case sIdle: {
                    Idle ctx;
                    ctx.step();
                    // examine state
                    // get user input or
                    // call step() again or
                    // decide next state:
                    current = Accelerate;
                    break;
                }
                ...
         }
    }
我喜欢这个设计的地方是简单,没有函子(与状态模式不同),并且当前状态在构建下一个状态之前被破坏。另外,与状态模式不同,状态实现不知道其他状态实现


不要把抽象放在那里。或者放在那里,但保留原始版本,然后比较。

太宽了。但请看“为MCU编写时避免继承”是荒谬的。也许他们是想避免使用虚拟函数,这仍然是一个值得商榷的建议?@JohnZwinck我在这里看到有人明确地指出了这一点。就我个人而言,我不明白为什么,但我不是专家…明确说明具体是什么?有一个链接你可以分享吗?如果你不想要继承,为什么你问C++。您是否对州模式感兴趣?应该是对的。继承并不意味着抽象。“抽象也不意味着继承。”胡安科潘萨稍加改写。现在,当您想要共享代码时,通常使用抽象,这是不好的,或者当您想要“使用一个类来代替另一个类”(关于这一点,有一段很好的引语,我不记得了)。我称之为抽象,它是“当一个代码在多个类之间共享时,不要使用继承,而是当一个代码与多个类一起工作时”。有人知道吗?那么,你为什么不建议使用Switch语句呢?@MartinRand我没有这么说。switch语句将是FSM主循环的一部分。每个案例都应该创建它的类,使用它,销毁它,并设置下一个状态。