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;
答案 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