state的实现

// state.cpp

#include <stdio.h>

#ifdef _X_RELEASE_
    #define TRACE(str)
#else
    #define TRACE(str) printf("%s/n", str)
#endif

class CContext; // CContext在CState有用到,要在此提前声明。
                // 注意类CContext的定义一定要放在CState类的实现之前,否则会有下列编译错误:
                /*
                state.cpp: In member function 'void CState::ChangeState(CContext*, CState*)':
                state.cpp:36: error: invalid use of incomplete type 'struct CContext'
                state.cpp:9: error: forward declaration of 'struct CContext'
                */

/*** 类的定义 ***/
class CState
{
public:
    CState()
    {
        TRACE("CState");
    }
   
    virtual ~CState()
    {
        TRACE("~CState");
    }
   
    // 状态行为接口,注意该接口有一个CContext类型的参数
    // 也可以在这里提供一个缺省的实现
    virtual void Handle(CContext* pContext) = 0;
   
    void ChangeState(CContext* pContext, CState* pState);
};

// 具体状态类,实现为单件。注意在该类中只有内存的分配,没有释放
class CConcreteStateA : public CState
{
private:
    static CConcreteStateA* m_pStateA;

private:
    CConcreteStateA()
    {
    }
   
public:
    static CConcreteStateA* Instance()
    {
        if (!m_pStateA)
        {
            m_pStateA = new CConcreteStateA();
        }

        return m_pStateA;
    }
   
public:
    virtual void Handle(CContext* pContext);
};

// 具体状态类,实现为单件。注意在该类中只有内存的分配,没有释放
class CConcreteStateB : public CState
{
private:
    static CConcreteStateB* m_pStateB;

private:
    CConcreteStateB()
    {
    }
   
public:
    static CConcreteStateB* Instance()
    {
        if (!m_pStateB)
        {
            m_pStateB = new CConcreteStateB();
        }

        return m_pStateB;
    }
   
public:
    virtual void Handle(CContext* pContext);
};

class CContext
{
private:
    CState* m_pState; // 当前状态

private:
    friend void CState::ChangeState(CContext* pContext, CState* pState);
   
    void ChangeState(CState* pState) // 改变当前状态
    {
        TRACE("CContext::ChangeState");
        m_pState = pState;
    }
   
public:
    CContext()
    {
        TRACE("CContext");

        // 假设初始状态为CConcreteStateA,当然初始状态也可以作为构造函数的参数传入
        m_pState = CConcreteStateA::Instance();
    }
   
    virtual ~CContext()
    {
        TRACE("~CContext");
        m_pState = 0;
    }
   
    void Request()
    {
        TRACE("Request");
       
        if (m_pState)
        {
            m_pState->Handle(this); // 调用状态行为接口
        }
    }

};

/*** 类的实现 ***/
void CState::ChangeState(CContext* pContext, CState* pState)
{
    TRACE("CState::ChangeState");
   
    // 调用CContext类的ChangeState函数进行状态转换
    pContext->ChangeState(pState);
}

CConcreteStateA* CConcreteStateA::m_pStateA = 0;

void CConcreteStateA::Handle(CContext* pContext)
{
    TRACE("CConcreteStateA::Handle");
   
    ChangeState(pContext, CConcreteStateB::Instance());
}

CConcreteStateB* CConcreteStateB::m_pStateB = 0;

void CConcreteStateB::Handle(CContext* pContext)
{
    TRACE("CConcreteStateB::Handle");
   
    ChangeState(pContext, CConcreteStateA::Instance());
}

int main()
{
    CContext* pContext = new CContext();
    pContext->Request();
    TRACE("-----");
   
    pContext->Request();
    TRACE("-----");
   
    pContext->Request();
    TRACE("-----");

    delete pContext;
    pContext = 0;

    return 0;
}

/*
root@ubuntu:/home/hgc/test# g++ state.cpp -o state -g -Wall
root@ubuntu:/home/hgc/test# ./state
CContext
CState
Request
CConcreteStateA::Handle
CState
CState::ChangeState
CContext::ChangeState
-----
Request
CConcreteStateB::Handle
CState::ChangeState
CContext::ChangeState
-----
Request
CConcreteStateA::Handle
CState::ChangeState
CContext::ChangeState
-----
~CContext
*/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值