无法编译 FSM 示例代码

发布于 2024-07-10 07:55:45 字数 1544 浏览 5 评论 0原文

Robert 有一个很好的状态机教程,名为 UML 教程:有限状态机 C.马丁. 但我无法编译它提供的示例代码。 我得到 *FsmTest.cpp(46) :错误 C2664:'SetState':无法将参数 1 从 'class UnlockedState *' 转换为 'class TurnstileState '

请帮忙。 谢谢。

class Turnstile
{
public:
    virtual void Lock();
    virtual void Unlock();
    virtual void Thankyou();
    virtual void Alarm();
};

class TurnstileFSM;
class LockedState;
class UnlockedState;

class TurnstileState
{
public:
    virtual void Coin(TurnstileFSM*) = 0;
    virtual void Pass(TurnstileFSM*) = 0;
protected:
    static LockedState lockedState;
    static UnlockedState unlockedState;
};

class TurnstileFSM : public Turnstile
{
public:
    void SetState(TurnstileState* s) {itsState = s;}
    void Coin() {itsState->Coin(this);}
    void Pass() {itsState->Pass(this);}


private:
    TurnstileState *itsState;
};

class LockedState : public TurnstileState
{
public:
    virtual void Coin(TurnstileFSM* t)
    {
        t->SetState(&unlockedState);
        t->Unlock();
    }
    virtual void Pass(TurnstileFSM* t)
    {
        t->Alarm();
    }
};

class UnlockedState : public TurnstileState
{
public:
    virtual void Coin(TurnstileFSM* t)
    {
        t->Thankyou();
    }
    virtual void Pass(TurnstileFSM* t)
    {
        t->SetState(&lockedState);
        t->Lock();
    }
};

LockedState TurnstileState::lockedState;
UnlockedState TurnstileState::unlockedState;

There is a nice state machine tutorial called UML Tutorial: Finite State Machines by Robert C. Martin. But I can't compile the sample code it provides. I got *FsmTest.cpp(46) : error C2664: 'SetState' : cannot convert parameter 1 from 'class UnlockedState *' to 'class TurnstileState '

Please, help. Thanks.

class Turnstile
{
public:
    virtual void Lock();
    virtual void Unlock();
    virtual void Thankyou();
    virtual void Alarm();
};

class TurnstileFSM;
class LockedState;
class UnlockedState;

class TurnstileState
{
public:
    virtual void Coin(TurnstileFSM*) = 0;
    virtual void Pass(TurnstileFSM*) = 0;
protected:
    static LockedState lockedState;
    static UnlockedState unlockedState;
};

class TurnstileFSM : public Turnstile
{
public:
    void SetState(TurnstileState* s) {itsState = s;}
    void Coin() {itsState->Coin(this);}
    void Pass() {itsState->Pass(this);}


private:
    TurnstileState *itsState;
};

class LockedState : public TurnstileState
{
public:
    virtual void Coin(TurnstileFSM* t)
    {
        t->SetState(&unlockedState);
        t->Unlock();
    }
    virtual void Pass(TurnstileFSM* t)
    {
        t->Alarm();
    }
};

class UnlockedState : public TurnstileState
{
public:
    virtual void Coin(TurnstileFSM* t)
    {
        t->Thankyou();
    }
    virtual void Pass(TurnstileFSM* t)
    {
        t->SetState(&lockedState);
        t->Lock();
    }
};

LockedState TurnstileState::lockedState;
UnlockedState TurnstileState::unlockedState;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

空城旧梦 2024-07-17 07:55:45

问题是,当您尝试在 LockedState::Coin() 内部调用 SetState() 时,类 UnlockedState 是一个 不完整类型:已声明但未定义。 为了修复它,您需要将 Coin() 的定义移至 UnlockedState 的定义之后:

class LockedState : public TurnstileState
{
public:
    virtual void Coin(TurnstileFSM* t);
    ...
};

class UnlockedState : public TurnstileState
{
    ...
};

void LockedState::Coin(TurnstileFSM* t)
{
    ...
}

The problem is that when you try to call SetState() inside of LockedState::Coin(), the class UnlockedState is an incomplete type: it has been declared but not defined. In order to fix it, you'll need to move the definition of of Coin() to after that of UnlockedState:

class LockedState : public TurnstileState
{
public:
    virtual void Coin(TurnstileFSM* t);
    ...
};

class UnlockedState : public TurnstileState
{
    ...
};

void LockedState::Coin(TurnstileFSM* t)
{
    ...
}
眼泪也成诗 2024-07-17 07:55:45

这很可能是因为它还不知道 UnlockedState 是 TurnstileState 的子类。 将函数从类内部删除到文件末尾:

class TurnstileFSM {
    void SetState(TurnstileState* s);
};

void TurnstileFSM::SetState(TurnstileState* s) {itsState = s;}

Most likely this is because it does not know UnlockedState is a subclass of TurnstileState yet. Remove the function from inside the class to the end of the file:

class TurnstileFSM {
    void SetState(TurnstileState* s);
};

void TurnstileFSM::SetState(TurnstileState* s) {itsState = s;}
不羁少年 2024-07-17 07:55:45

在示例中,生成的代码应包含 tscontext.h,并且 TurnStyle 类是从上下文派生的,应在 *tscontext.h 中将其声明为 < em>class TurnStyleContext

在我的例子中,生成的代码如下所示:

    #include "tscontext.h"   // the header file name for the context class"

    // Forward Declarations

    class TurnStyle;

    //----------------------------------------------
    // TurnStyleState: The base state class
    //----------------------------------------------
    class TurnStyleState
    {
      public: 
        virtual const char* StateName() const = 0;
        virtual void Coin( TurnStyle& );
        virtual void Pass( TurnStyle& );
    };

    //----------------------------------------------
    // State: Unlocked
    //----------------------------------------------
    class TurnStyleUnlockedState : public TurnStyleState
    {
      public: 
        virtual const char* StateName() const
            { return "Unlocked"; }
        virtual void Pass( TurnStyle& );
        virtual void Coin( TurnStyle& );
    };
    //----------------------------------------------
    // State: Locked
    //----------------------------------------------
    class TurnStyleLockedState : public TurnStyleState
    {
      public: 
        virtual const char* StateName() const
            { return "Locked"; }
        virtual void Coin( TurnStyle& );
        virtual void Pass( TurnStyle& );
    };
    //----------------------------------------------
    // TurnStyle: The Finite State Machine class
    //----------------------------------------------
    class TurnStyle: public TurnStyleContext
    {
      public: 
        // Static State variables
        static TurnStyleUnlockedState Unlocked;
        static TurnStyleLockedState Locked;

        TurnStyle(); // default Constructor

        // Event functions
        virtual void Coin() { itsState->Coin( *this ); }
        virtual void Pass() { itsState->Pass( *this ); }

        // State Accessor functions
        void SetState( TurnStyleState& theState ) { itsState = &theState; }
        TurnStyleState& GetState() const { return *itsState; }

        const char* GetCurrentStateName() const { return itsState->StateName(); }
        const char* GetVersion() const;

      private: 
        TurnStyleState* itsState;
    };

状态机以这种方式定义:

Context TurnStyleContext     // the name of the context class
FSMName TurnStyle            // the name of the FSM to create
Initial Locked               // the name of the initial state
                             // for C++ output
pragma Header  tscontext.h"   // the header file name for the context class, note the necessary "
{
    Locked
    {
        Coin     Unlocked    Unlock
        Pass     Locked      Alarm
    }
    Unlocked <BeforeUnlocked >AfterUnlocked
    {
        Coin    Unlocked    Thankyou
        Pass    Locked      Lock
    }
}

上下文实现FSMError、Thankyou、Lock、Alarm、Unlock、BeforeUnlocked、AfterUnlocked

In the example, the generated code should include the tscontext.h, and the TurnStyle class is derived from the context, which should be declared in *tscontext.h" as class TurnStyleContext.

In my case the generated code looks like this:

    #include "tscontext.h"   // the header file name for the context class"

    // Forward Declarations

    class TurnStyle;

    //----------------------------------------------
    // TurnStyleState: The base state class
    //----------------------------------------------
    class TurnStyleState
    {
      public: 
        virtual const char* StateName() const = 0;
        virtual void Coin( TurnStyle& );
        virtual void Pass( TurnStyle& );
    };

    //----------------------------------------------
    // State: Unlocked
    //----------------------------------------------
    class TurnStyleUnlockedState : public TurnStyleState
    {
      public: 
        virtual const char* StateName() const
            { return "Unlocked"; }
        virtual void Pass( TurnStyle& );
        virtual void Coin( TurnStyle& );
    };
    //----------------------------------------------
    // State: Locked
    //----------------------------------------------
    class TurnStyleLockedState : public TurnStyleState
    {
      public: 
        virtual const char* StateName() const
            { return "Locked"; }
        virtual void Coin( TurnStyle& );
        virtual void Pass( TurnStyle& );
    };
    //----------------------------------------------
    // TurnStyle: The Finite State Machine class
    //----------------------------------------------
    class TurnStyle: public TurnStyleContext
    {
      public: 
        // Static State variables
        static TurnStyleUnlockedState Unlocked;
        static TurnStyleLockedState Locked;

        TurnStyle(); // default Constructor

        // Event functions
        virtual void Coin() { itsState->Coin( *this ); }
        virtual void Pass() { itsState->Pass( *this ); }

        // State Accessor functions
        void SetState( TurnStyleState& theState ) { itsState = &theState; }
        TurnStyleState& GetState() const { return *itsState; }

        const char* GetCurrentStateName() const { return itsState->StateName(); }
        const char* GetVersion() const;

      private: 
        TurnStyleState* itsState;
    };

with the state machine defined this way:

Context TurnStyleContext     // the name of the context class
FSMName TurnStyle            // the name of the FSM to create
Initial Locked               // the name of the initial state
                             // for C++ output
pragma Header  tscontext.h"   // the header file name for the context class, note the necessary "
{
    Locked
    {
        Coin     Unlocked    Unlock
        Pass     Locked      Alarm
    }
    Unlocked <BeforeUnlocked >AfterUnlocked
    {
        Coin    Unlocked    Thankyou
        Pass    Locked      Lock
    }
}

The context implements FSMError, Thankyou, Lock, Alarm, Unlock, BeforeUnlocked, AfterUnlocked

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文