1

有一个很好的状态机教程,名为UML 教程: Robert C. Martin 的有限状态机。但我无法编译它提供的示例代码。我得到 *FsmTest.cpp(46) : error C2664: 'SetState' : cannot convert parameter 1 from 'class UnlockedState *' to '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;
4

3 回答 3

5

问题是当您尝试调用SetState()inside ofLockedState::Coin()时,该类UnlockedState是一个不完整的类型:它已被声明未定义。为了修复它,您需要将 of 的定义移到 ofCoin()之后UnlockedState

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

class UnlockedState : public TurnstileState
{
    ...
};

void LockedState::Coin(TurnstileFSM* t)
{
    ...
}
于 2008-12-22T20:30:53.970 回答
1

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

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

void TurnstileFSM::SetState(TurnstileState* s) {itsState = s;}
于 2008-12-22T20:28:56.330 回答
0

在示例中,生成的代码应该包含tscontext.h,并且TurnStyle类是从上下文中派生的,应该在 *tscontext.h" 中声明为类 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

于 2012-04-25T09:33:19.770 回答