编程模仿boost::function和boost::bind(一)

2014-11-23 22:19:39 · 作者: · 浏览: 15
boost::function和boost::bind结合使用是非常强大的,他可以将成员函数和非成员函数绑定对一个对象上,实现了类似C#的委托机制。委托在许多时候可以替代C++里面的继承,实现对象解耦,简单说就是把产生事件的代码和处理事件的代码通过委托者给隔离开来。
但是boost库是非常庞大的,尤其是在发布开源软件时, 下载安装boost是一件让用户望而却步的事情。基于此,下面 编程模拟boost::function和boost::bind。
为了满足90%以上的应用场合,该代码实现以下目标:
1.支持成员函数和非成员函数绑定。
2.支持多个参数(最多9个),代码中使用#define宏定义了1到9个参数的版本。
3.为了在大规模应用中多次分配function对象造成内存碎片,对new和delete进行重载,方便使用内存池管理内存。
下面贴出代码:
/* 
 *  Author:         chzuping 
 *  Email:          chzuping@gmail.com 
 *  description:    模拟boost::bind和boost::function 
 */  
#pragma  once;  
#ifndef ZWBIND_MALLOC  
    #define ZWBIND_MALLOC malloc  
#endif  
#ifndef ZWBIND_FREE  
    #define ZWBIND_FREE free  
#endif  
namespace ZwBind  
{  
    class bind_base  
    {  
    public:  
        static void *operator new(size_t size )  
        {  
            return ZWBIND_MALLOC(size);  
        }  
        static void operator delete( void *ptr)  
        {  
            ZWBIND_FREE(ptr);  
        }  
    };  
    template  
    class bind_base0:public bind_base  
    {  
    public:  
        virtual ret_type callfun() = 0;  
        ret_type operator()()  
        {  
            return callfun();  
        }  
    };  
    template  
    class bindobj0 : public bind_base0  
    {  
    public:  
        bindobj0(obj_type* pobject, ret_type (obj_type::*pmemfun)())  
        {  
            m_pobject = pobject;  
            m_pmemfun = pmemfun;  
        }  
        virtual int callfun()  
        {  
            return (m_pobject->*m_pmemfun)();  
        }  
    private:  
        obj_type* m_pobject;  
        ret_type (obj_type::* m_pmemfun)();  
    };  
    template  
    class bind0 : public bind_base0
{ public: bind0( ret_type (*pfun)()) { m_pfun = pfun; } virtual ret_type callfun() { return m_pfun(); } private: ret_type (*m_pfun)(); }; template bindobj0* bindfun(obj_type* pclass, ret_type (obj_type::*pmemfun)()) { void *pRet = NULL; bindobj0* pbind = new bindobj0(pclass, pmemfun); return pbind; } template bind0* bindfun(ret_type (*pmemfun)()) { bind0* pbind = new bind0(pmemfun); return pbind; } #define DECLARE_PARAMS(...) __VA_ARGS__ #define DECLARE_TPYE(...) __VA_ARGS__ #define DECLARE_ARGS(...) __VA_ARGS__ #define DECLARE_VAR(...) __VA_ARGS__ #define DECLARE_SIGSLOT(index, ptype,classparam,args,var) \ template\ class bind_base##index\ {\ public:\ virtual ret_type callfun(args) = 0;\ ret_type operator()(args)\ {\ return callfun(var);\ }\ };\ template \ class bindobj##index:public bind_base##index\ {\ public:\ bindobj##index(obj_type* pobject, ret_type (obj_type::*pmemfun)(args))\ {\ m_pobject = pobject;\ m_pmemfun = pmemfun;\ }\ virtual ret_type callfun(args)\ {\ return (m_pobject->*m_pmemfun)(var);\ }\ private:\ obj_type* m_pobject;\ ret_type (obj_type::* m_pmemfun)(args);\ };\ template\ class bind##index : public bind_base##index\ {\ public:\ bind##index(ret_type (*pfun)(args))\ {\ m_pfun = pfun;\ }\ virtual ret_type callfun(args)\ {\ return m_pfun(var);\ }\ private:\ ret_type (*m_pfun)(args);\ };\ template \ bindobj##index* bindfun(obj_type* pclass, ret_type (obj_type::*pmemfun)(args))\ {\ void *pRet = NULL;\ bindobj##index* pbind = new bindobj##index(pclass, pmemfun);\ return pbind;\ }\ template\ bind##index* bindfun(ret_type (*pmemfun)(args))\ {\ bind##index* pbind = new bind##index(pmemfun);\ return pbind;\ } DECLARE_SIGSLOT(1,DECLARE_PARAMS(arg1_type), DECLARE_TPYE(cl