之前实现过C++11的delegate,为了学习,手动实现一个03版本的。

没有可变模板参数,一切都是体力活。C++11下有function类,可以很轻松实现。于是从C++03开始,就从function造轮子。。

function轮子的主要代码如下:

#ifndef FUNCTION_CPLUSPLUS_03
#define FUNCTION_CPLUSPLUS_03

#include <iostream>
using namespace std;

namespace li
{ 

//关于仿函数...可以显式指定 如 function<void(testClass1::*)(int,string)> f3( &testClass1::operator(), &tc0 );  或者function<void(testClass1::*)(int,string)> f3(&tc0);
//关于拷贝构造等其他构造函数...太懒了...遇到坑再添加
//已经添加有cv属性的类成员的情况

//这里的function功能是没办法与C++11相比的,这里的function的主要目的是为实现delegate做类型擦除处理

#define TEMPLATE_PARA0 typename R
#define TEMPLATE_PARA1 TEMPLATE_PARA0 ,typename P1
#define TEMPLATE_PARA2 TEMPLATE_PARA1 ,typename P2
#define TEMPLATE_PARA3 TEMPLATE_PARA2 ,typename P3
#define TEMPLATE_PARA4 TEMPLATE_PARA3 ,typename P4
#define TEMPLATE_PARA5 TEMPLATE_PARA4 ,typename P5
#define TEMPLATE_PARA6 TEMPLATE_PARA5 ,typename P6
#define TEMPLATE_PARA7 TEMPLATE_PARA6 ,typename P7
#define TEMPLATE_PARA8 TEMPLATE_PARA7 ,typename P8

#define TEMPLATE_PARA0_INS
#define TEMPLATE_PARA1_INS P1 p1
#define TEMPLATE_PARA2_INS TEMPLATE_PARA1_INS , P2 p2
#define TEMPLATE_PARA3_INS TEMPLATE_PARA2_INS , P3 p3
#define TEMPLATE_PARA4_INS TEMPLATE_PARA3_INS , P4 p4
#define TEMPLATE_PARA5_INS TEMPLATE_PARA4_INS , P5 p5
#define TEMPLATE_PARA6_INS TEMPLATE_PARA5_INS , P6 p6
#define TEMPLATE_PARA7_INS TEMPLATE_PARA6_INS , P6 p7
#define TEMPLATE_PARA8_INS TEMPLATE_PARA7_INS , P6 p8

#define TEMPLATE_PARA0_N R
#define TEMPLATE_PARA1_N TEMPLATE_PARA0_N , P1
#define TEMPLATE_PARA2_N TEMPLATE_PARA1_N , P2
#define TEMPLATE_PARA3_N TEMPLATE_PARA2_N , P3
#define TEMPLATE_PARA4_N TEMPLATE_PARA3_N , P4
#define TEMPLATE_PARA5_N TEMPLATE_PARA4_N , P5
#define TEMPLATE_PARA6_N TEMPLATE_PARA5_N , P6
#define TEMPLATE_PARA7_N TEMPLATE_PARA6_N , P7
#define TEMPLATE_PARA8_N TEMPLATE_PARA7_N , P8

enum FunType
{
    Normal,
    Member
};

template<typename R,typename P1=void,typename P2=void,typename P3=void,
    typename P4=void,typename P5=void,typename P6=void,typename P7=void,typename P8=void,typename P9=void>
class function_impl;
 

#define FUNCTION_IMPL(id)   \
template<TEMPLATE_PARA##id> \
class function_impl<TEMPLATE_PARA##id##_N>  \
{ \
public: \
function_impl(){};  \
virtual R operator()(TEMPLATE_PARA##id##_INS)=0;  \
    virtual ~function_impl(){}; \
    virtual FunType getFunType(){return Normal;}\
};  


  
FUNCTION_IMPL(0)
FUNCTION_IMPL(1)
FUNCTION_IMPL(2)
FUNCTION_IMPL(3)
FUNCTION_IMPL(4)
FUNCTION_IMPL(5)
FUNCTION_IMPL(6)
FUNCTION_IMPL(7)
FUNCTION_IMPL(8)
/**************************************************************************************************/
 

template<typename F>
class function;
 
#define TEMPLATE_PARA0_N1 
#define TEMPLATE_PARA1_N1  P1
#define TEMPLATE_PARA2_N1 TEMPLATE_PARA1_N1 , P2
#define TEMPLATE_PARA3_N1 TEMPLATE_PARA2_N1 , P3
#define TEMPLATE_PARA4_N1 TEMPLATE_PARA3_N1 , P4
#define TEMPLATE_PARA5_N1 TEMPLATE_PARA4_N1 , P5
#define TEMPLATE_PARA6_N1 TEMPLATE_PARA5_N1 , P6
#define TEMPLATE_PARA7_N1 TEMPLATE_PARA6_N1 , P7
#define TEMPLATE_PARA8_N1 TEMPLATE_PARA7_N1 , P8

#define PARA_LIST0
#define PARA_LIST1 p1
#define PARA_LIST2 PARA_LIST1 ,p2
#define PARA_LIST3 PARA_LIST2 ,p3
#define PARA_LIST4 PARA_LIST3 ,p4
#define PARA_LIST5 PARA_LIST4 ,p5
#define PARA_LIST6 PARA_LIST5 ,p6
#define PARA_LIST7 PARA_LIST6 ,p7
#define PARA_LIST8 PARA_LIST7 ,p8

#define FUNCTION(id) \
template<TEMPLATE_PARA##id> \
class function<R(TEMPLATE_PARA##id##_N1)> :public function_impl<TEMPLATE_PARA##id##_N> \
{  \
public:\
typedef R(*F)(TEMPLATE_PARA##id##_N1);\
    function(F f):func_(f){ };\
    R operator()(TEMPLATE_PARA##id##_INS) {return func_(PARA_LIST##id);}\
    void* getTarget()const\
{\
    return (void*)*func_;\
}\
    F func_; \
};


FUNCTION(0) 
FUNCTION(1)
FUNCTION(2)
FUNCTION(3)
FUNCTION(4)
FUNCTION(5)
FUNCTION(6)
FUNCTION(7)
FUNCTION(8)
 
 

/**************************************************************************************************/

#define FUNCTION_MEM(id,...) \
    template<class C, TEMPLATE_PARA##id> \
class function<R(C::*)(TEMPLATE_PARA##id##_N1)__VA_ARGS__> :public function_impl<TEMPLATE_PARA##id##_N>  \
{  \
public: \
    typedef R(C::*F)(TEMPLATE_PARA##id##_N1)__VA_ARGS__; \
    typedef C*  CPtr; \
    function(F f,C*cp):func_(f),c_ptr(cp){}; \
    function(C*cp):func_( &C::operator()),c_ptr(cp){}; \
    R operator()(TEMPLATE_PARA##id##_INS) \
{ \
    return (c_ptr->*func_)(PARA_LIST##id); \
} \
  FunType getFunType(){return Member;}\
 F getTarget()const\
{\
return func_;\
}\
 CPtr getTarCalssPtr() const\
{\
    return c_ptr;\
}\
protected: \
    F func_; \
    CPtr c_ptr;\
};

 
 FUNCTION_MEM(0)
 FUNCTION_MEM(1)
 FUNCTION_MEM(2)
 FUNCTION_MEM(3)
 FUNCTION_MEM(4)
 FUNCTION_MEM(5)
 FUNCTION_MEM(6)
 FUNCTION_MEM(7)
 FUNCTION_MEM(8)


 FUNCTION_MEM(0,const) 
 FUNCTION_MEM(1,const)
 FUNCTION_MEM(2,const)
 FUNCTION_MEM(3,const)
 FUNCTION_MEM(4,const)
 FUNCTION_MEM(5,const)
 FUNCTION_MEM(6,const)
 FUNCTION_MEM(7,const)
 FUNCTION_MEM(8,const)


 FUNCTION_MEM(0,volatile) 
 FUNCTION_MEM(1,volatile)
 FUNCTION_MEM(2,volatile)
 FUNCTION_MEM(3,volatile)
 FUNCTION_MEM(4,volatile)
 FUNCTION_MEM(5,volatile)
 FUNCTION_MEM(6,volatile)
 FUNCTION_MEM(7,volatile)
 FUNCTION_MEM(8,volatile)

 FUNCTION_MEM(0,const volatile) 
 FUNCTION_MEM(1,const volatile)
 FUNCTION_MEM(2,const volatile)
 FUNCTION_MEM(3,const volatile)
 FUNCTION_MEM(4,const volatile)
 FUNCTION_MEM(5,const volatile)
 FUNCTION_MEM(6,const volatile)
 FUNCTION_MEM(7,const volatile)
 FUNCTION_MEM(8,const volatile)
  
 };
#endif

然后再来造delegate的轮子,代码如下:

#ifndef DELEGATE_CPLUSPLUS_03
#define DELEGATE_CPLUSPLUS_03

#include "function.hpp"
#include <list>
#include <iostream>
using namespace std;

namespace li
{
     
    //此处参考 《Modern C++ Design》 一书,牛人牛书啊,不过这里暂时没用到,之前想的情况比较复杂,以为会用到,代码还是比较经典的,所有保留在此

    /*判断类型之间能否相互转换*/
    template<class T, class U>
    class Convert 
    {  
        static char Test(U); 
        static int Test(...); 
        static T MakeT(); 
    public: 
        enum { CanConvert =sizeof(Test(MakeT())) == sizeof(char) };  
    }; 
     

template<typename R=void,typename P1=void,typename P2=void,typename P3=void,
    typename P4=void,typename P5=void,typename P6=void,typename P7=void,typename P8=void,typename P9=void>
    class delegate;
     
    template<typename F,typename C>
    class deleMemHelper
    {
    public:
        deleMemHelper(F f,C*cptr):fun(f),c_ptr(cptr){}
        F fun;
        C*c_ptr;
    };

    template<typename F,typename C>
    deleMemHelper<F,C> makeDeleMemHelper(F f,C*cp)
    {
    return deleMemHelper<F,C>(f,cp);
    }

#define DELEGATE_CLASS(id) \
    template<TEMPLATE_PARA##id> \
    class delegate<R(TEMPLATE_PARA##id##_N1)> \
    { \
    public: \
    typedef li::function_impl<TEMPLATE_PARA##id##_N> dele_func;\
    typedef std::list<dele_func*> function_list;\
    typedef R(*func_type)(TEMPLATE_PARA##id##_N1);\
    typedef delegate<R(TEMPLATE_PARA##id##_N1)>  this_type;\
    \
    delegate(){};\
    ~delegate()\
    {\
      clear();\
    }\
    \
    \
    void clear()\
    {\
       for(typename function_list::iterator itr =func_list.begin();itr!= func_list.end(); itr++ )\
       {\
         delete *itr;\
       }\
       func_list.clear();\
    }\
    \
    this_type& operator+=(func_type fun)\
    {\
    func_list.push_back(new function<R(TEMPLATE_PARA##id##_N1)>(fun));\
    return *this;\
    }\
    this_type& operator-=(func_type fun)\
    {\
    for( function_list::iterator itr = func_list.begin(); itr!= func_list.end(); ++itr )\
    {\
      if((*itr)->getFunType()!=Normal) continue;\
       func_type p =(func_type)( ((function<R(TEMPLATE_PARA##id##_N1)>*)(*itr))->getTarget());\
       if(p && *p==fun)\
       {\
         delete *itr;\
         func_list.erase(itr);\
         break;\
       }\
    }\
    return *this;\
    }\
    \
    template<class C,class B>\
    this_type& operator+=(const deleMemHelper<R(C::*)(TEMPLATE_PARA##id##_N1),B>& delemh)\
    {\
      C* c_ptr = dynamic_cast<C*>(delemh.c_ptr);\
      if(!c_ptr) return *this;\
    func_list.push_back(new function<R(C::*)(TEMPLATE_PARA##id##_N1)>(delemh.fun, c_ptr));\
    return *this;\
    }\
    \
    template<class C,class B>\
        this_type& operator-=(const deleMemHelper<R(C::*)(TEMPLATE_PARA##id##_N1),B>& delemh)\
    {\
       for( function_list::iterator itr = func_list.begin(); itr!= func_list.end(); ++itr )\
      {\
         if((*itr)->getFunType()==Normal) continue;\
         function<R(C::*)(TEMPLATE_PARA##id##_N1)>*func = dynamic_cast<function<R(C::*)(TEMPLATE_PARA##id##_N1)>*>(*itr);\
         if(func==NULL) continue;\
          C*cp =func->getTarCalssPtr();\
          if(cp&& cp==delemh.c_ptr )\
          {\
           if( func->getTarget() == delemh.fun )\
           {\
                delete *itr;  \
                func_list.erase(itr);\
                break;\
           }\
           \
         }\
      }\
    return *this;\
    }\
    \
    \
    void operator()(TEMPLATE_PARA##id##_INS)\
    {\
    for (typename function_list::iterator itr = func_list.begin(); itr != func_list.end(); itr++)\
    {\
    try\
    {\
    (*(*itr))(PARA_LIST##id);\
    }\
    catch (exception ex)\
    {\
    \
    }\
    }\
    }\
    private: \
     function_list func_list;\
    }; 

  
DELEGATE_CLASS(0)
DELEGATE_CLASS(1)
DELEGATE_CLASS(2)
DELEGATE_CLASS(3)
DELEGATE_CLASS(4)
DELEGATE_CLASS(5)
DELEGATE_CLASS(6)
DELEGATE_CLASS(7)
DELEGATE_CLASS(8)

};
#endif

测试用例如下:

 
#include "function.hpp" 
#include "delegate.hpp"
#include <string>
#include <iostream>
 
using namespace std;
using namespace li;

void funTest(int a,string b)
{
     cout<<"funTest"<<"  "<<a<<endl; 
}


class testClass
{
public:
    testClass(int i):i(i){}
    void funTest(int a,string b)
    {
        cout<<"testClass  "<< i<<"    "<<a <<"    "<<b<<endl;
    }
    int i;
};

class A
{
   public:
    virtual void funTest(int a,string b)
    {
        cout<<"A虚函数测试  "<< "    "<<a <<"    "<<b<<endl;
    }
};

class C:public    A
{
public:
    void funTest(int a,string b)
    {
        cout<<"C虚函数测试  "<< "    "<<a <<"    "<<b<<endl;
    }
};



class testClass1
{
public:
    testClass1(int i):i(i){}
    void funTest(int a,string b)
    {
        cout<<"testClass1  "<< i<<"    "<<a <<"    "<<b<<endl;
    }

    void operator()(int a,string b)
    {
        cout<<"testClass1 operator()  "<< i<<"    "<<a <<"    "<<b<<endl;
    }

    int i;
};

int sft(int a, const string& b,double c)
{ 
    cout<<a<<"  "<< b<<"  "<<c<<endl;
    return 3333;
}

int sft1(int a, const string& b,double c,C &)
{ 
    return 3333;
}
 
 
int main(int argc, char* argv[])
{       
     function<int(int, const string&,double)>  f = sft;
     function<int(int, const string&,double,C&)>  f1 = sft1;
      
     f(4,string("asdfasdfasdfasdfasdfasdfas"),.0333); 

     testClass1 tc0(3);

     function<void(testClass1::*)(int,string)> f3( &testClass1::operator(), &tc0 );
     f3(99,"");

     function<void(testClass1::*)(int,string)> f4(&tc0);
     f4(98,"d");
     cout<<"*********************单个函数测试完*******************"<<endl;

    testClass tc(1);
    testClass tc1(2);
     
    testClass1 tc21(1);
    testClass1 tc22(2);
     
 
    C c;

    delegate<void(int,string)> de; 
 

    de+=funTest;
    de+=makeDeleMemHelper(&testClass::funTest,&tc);
    de+=makeDeleMemHelper(&testClass::funTest,&tc1);
    de+=makeDeleMemHelper(&C::funTest,&c);
    de(3,"afasdfasdfas");
    cout<<"***********************************************************"<<endl;
  
    de-=funTest; 
    de+=makeDeleMemHelper(&testClass1::funTest,&tc21);
    de(4,"afasdfasdfas");
    cout<<"***********************************************************"<<endl;
 
    de-=makeDeleMemHelper(&testClass::funTest,&tc);
    de+=makeDeleMemHelper(&testClass1::funTest,&tc22);
    de+=funTest;
     de(5,"afasdfasdfas");
    cout<<"***********************************************************"<<endl;
   
    de-=makeDeleMemHelper(&testClass::funTest,&tc1); 
    de-=makeDeleMemHelper(&testClass1::funTest,&tc22); 
    de-=makeDeleMemHelper(&C::funTest,&c);
    de(6,"afasdfasdfas");
    cout<<"***********************************************************"<<endl;
    de.clear();
    de(7,"asdfa");
    cout<<"*******************end end end************************"<<endl;
    return 0;
}

测试编译器VS2010 ,测试结果如下:

 

详细代码说明如下:

未完待续。。。

 

posted on 2014-05-21 15:22  蜀山  阅读(715)  评论(0编辑  收藏  举报