Creative Commons License
本Blog采用 知识共享署名-非商业性使用-禁止演绎 3.0 Unported许可协议 进行许可。 —— Fox <游戏人生>

游戏人生

游戏人生 != ( 人生 == 游戏 )
站点迁移至:http://www.yulefox.com。请订阅本博的朋友将RSS修改为http://feeds.feedburner.com/yulefox
posts - 62, comments - 508, trackbacks - 0, articles - 7

作者:Fox

本文同时发布在http://www.yulefox.comhttp://www.cppblog.com/fox

十天之前,在CPPBLOG上写了一篇,有同学提到该实现不支持成员函数。这个问题我也考虑到了,既然被提出来,不妨把实现提供出来。

需要说明的是,我本身对template比较不感冒,不过对template感冒,而且写过关于成员函数指针的问题,想了很久,如果支持成员函数指针,不用模板是不行了。

此处对成员函数的支持还不涉及对函数参数的泛化,因为我这个消息映射暂时不需要参数泛化,下面的代码应该不需要过多的解释了。

#define REG_MSG_FUNC(nMsgType, MsgFunc) \
    CMsgRegister::RegisterCallFunc(nMsgType, MsgFunc);

#define REG_MSG_MEM_FUNC(nMsgType, Obj, MsgFunc) \
    CMsgRegister::RegisterCallFunc(nMsgType, Obj, MsgFunc);

class CBaseMessage;

class CHandler
{
public:
    virtual int operator()(CBaseMessage* pMsg) = 0;
};

template<typename FuncType>
class CDefHandler : public CHandler
{
public:
    CDefHandler(){}
    CDefHandler(FuncType &Func)
        : m_Func(Func)
    {
    }

    virtual int operator()(CBaseMessage* pMsg)
    {
        return m_Func(pMsg);
    }

protected:
    FuncType    m_Func;
};

template<typename ObjType, typename FuncType>
class CMemHandler : public CHandler
{
public:
    CMemHandler(){}
    CMemHandler(ObjType* pObj, FuncType Func)
        : m_pObj(pObj)
        , m_Func(Func)
    {
    }

    virtual int operator()(CBaseMessage* pMsg)
    {
        return (m_pObj->*m_Func)(pMsg);
    }

protected:
    FuncType    m_Func;
    ObjType*    m_pObj;
};

class CFunction
{
public:
    CFunction()
        : m_pHandler(NULL)
    {
    }

    // 封装(C函数或静态成员函数)
    template<typename FuncType>
    CFunction( FuncType &Func )
        : m_pHandler(new CDefHandler<FuncType>(Func))
    {
    }

    // 封装(非静态成员函数)
    template<typename ObjType, typename FuncType>
    CFunction( ObjType* pObj, FuncType Func )
        : m_pHandler(new CMemHandler<ObjType, FuncType>(pObj, Func))
    {
    }

    virtual ~CFunction()
    {
        DELETE_SAFE(m_pHandler);
    }

        // 函数调用
    int operator()(CBaseMessage* pMsg)
    {
        return (*m_pHandler)(pMsg);
    }

private:
    CHandler    *m_pHandler;
};

typedef std::map<int, CFunction*> MSG_MAP;
typedef MSG_MAP::iterator MSG_ITR;

class CMsgRegister
{
public:
    // 注册消息函数(C函数或静态成员函数)
    template <typename FuncType>
    inline static void RegisterCallFunc(int nMsgType, FuncType &Func)
    {
        CFunction *func = new CFunction(Func);
        s_MsgMap[nMsgType] = func;
    }

    // 注册消息函数(非静态成员函数)
    template <typename ObjType, typename FuncType>
    inline static void RegisterCallFunc(int nMsgType, ObjType* pObj, FuncType Func)
    {
        CFunction *func = new CFunction(pObj, Func);
        s_MsgMap[nMsgType] = func;
    }

    // 执行消息
    inline static void RunCallFunc(int nMsgType, CBaseMessage* pMsg)
    {
        MSG_ITR itr = s_MsgMap.find(nMsgType);
        if( s_MsgMap.end() != itr )
        {
            (*itr->second)(pMsg);
        }
    }

    static void ReleaseMsgMap()                // 释放消息映射表
    {
        MSG_ITR itr = s_MsgMap.begin();
        while( itr != s_MsgMap.end() )
        {
            DELETE_SAFE(itr->second);
            itr = s_MsgMap.erase(itr);
        }
    }

protected:
    static MSG_MAP            s_MsgMap;        // 消息映射表
};

不可否认,模板给了你更大的想象空间,很多东西,还是不要一味排斥的好:)。

Feedback

# re: 支持成员函数指针的消息映射机制的简单实现[未登录]  回复  更多评论   

2008-10-10 12:10 by cppexplore
...............
首页上,你上篇文章之前的文章就是有关 成员函数委托 的,两篇文章紧挨着

# re: 支持成员函数指针的消息映射机制的简单实现  回复  更多评论   

2008-10-10 15:33 by RichardHe
模板还是不会用啊....好想学...

# re: 支持成员函数指针的消息映射机制的简单实现  回复  更多评论   

2008-10-10 21:13 by Condor
不错,我也写了篇
http://www.cppblog.com/rise-worlds/archive/2008/10/10/63693.html

# re: 支持成员函数指针的消息映射机制的简单实现  回复  更多评论   

2008-10-11 18:20 by cv
楼主还是学生吧?
只怕你那东西自己都不知道要怎么用。
既然是采用了消息机制,那就该是事件驱动。。。
不知道你想做什么。

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理