无法编译FSM示例代码

时间:2008-12-22 20:19:50

标签: c++ state-machine

Robert C. Martin提供了一个名为UML Tutorial: Finite State Machines的状态机教程。但我无法编译它提供的示例代码。我得到* 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;

3 个答案:

答案 0 :(得分:5)

问题在于,当您尝试在SetState()内拨打LockedState::Coin()时,课程UnlockedState不完整类型:它已经已声明已定义。要解决此问题,您需要将Coin()的定义移至UnlockedState的定义之后:

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

class UnlockedState : public TurnstileState
{
    ...
};

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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

在该示例中,生成的代码应包含 tscontext.h TurnStyle 类派生自上下文,应在* tscontext.h中声明。 “as 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