我的C++委托类最终版

2005-07-28 15:49  重写了所有代码,不再把对象指针和函数指针转换为void*,而是保留原类型,通过虚函数让编译器来完成绑定。新版本下载

2005-07-27 10:36  返回值为void的特化版本改为直接循环,其它返回值的处理方式不变,依旧是Ret r = call(...); for (;;;) ret = call (...);这种方式。以后有好的方案再修改。

2005-07-26 21:36  修正G++编译的版本段错误(感谢 问题男),经初步测试没有发现问题。

2005-07-26 09:51  修正call函数中缺少typename的错误(感谢bcpl ),增加了Makefile(需要系统中安装有python),段错误的大问题还没有解决(确认VC8中不存在这问题)。

2005-07-25 23:55  修正代码生成器脚本中的2处错误,修正处理返回值的失误,增加测试代码。


相比前一版本,修改了以下几点(下标从0开始:))
0、类名改为Delegate。
1、采用Delegate < int& (const stirng&, float) > d这样的语法,更直观(学boost::function的)。
2、可以绑定仿函数了。
3、支持最多26个参数。。。(使用python脚本生成的,用宏太累)
4、如果返回值不是void,那么当委托没有绑定任何对象时,调用将抛出DelegateNotHandled异常。
5、支持=、+=、()操作符。
6、支持绑定委托对象。因为委托对象本身也是个仿函数,所以这里把它按仿函数来处理了。


重要提示:
0、Delegate.h文件是由generator.py读取其它3个文件,并替换其中定义的格式化字符串来生成的。
1、不要用它来绑定多继承类的成员函数。

扩充话题:
和boost::function比较,本文的Delegate类型要求比较严格,我认为这是好事。boost::function可以定义一个int(int)类型的function,但绑定一个short(double)类型的函数,实际并不是好事,我认为。

Delegate解决这类问题的方法是使用Adapter,这里给一个例子:

short  funcB ( double  d)
{
    
return  ( short )d;
}

struct  FuncA2FuncBAdapter
{
    Delegate 
< short ( double ) >  adapter;
    
int   operator  ( ) ( int  n)
    {
        
return  ( int )adapter (( double )n);
    }
};

int  main ()
{
    Delegate 
< int ( int ) >  d_test;
    FuncA2FuncBAdapter adp;
    d_test 
+=  adp;
    adp.adapter 
+=  funcB;
    d_test (
3 );
    
return   0 ;
}

这样可以明确地把强制转型的责任交给程序员,而不是编译器偷偷的做。

用Adapter还可以做更复杂的,下面这个boost::function就不能直接转了:

pair < short short >  funcB ( double  a,  int  b)
{
    
return  make_pair(( short )a, ( short )b);
}

struct  FuncA2FuncBAdapter
{
    Delegate 
< pair < short short > ( double int ) >  adapter;
    
int   operator  ( ) ( int  n)
    {
        
return  ( int )adapter (( double )n, n + 5 ).first;
    }
};

int  main ()
{
    Delegate 
< int ( int ) >  d_test;
    FuncA2FuncBAdapter adp;
    d_test 
+=  adp;
    adp.adapter 
+=  funcB;
    d_test (
3 );
    
return   0 ;
}

另一个差别是本文的Delegate类是多分派的。

下载:
http://files.cnblogs.com/cpunion/Delegate.rar

感谢:
  问题男  bcpl  刘未鹏(blog中关于函数类型的讲解)。

刚在 comp.lang.c++@googlegroups.com上看到的一个CallBack类,摘录在此。

//  file sltest.h
#ifndef SLTEST_H
#define  SLTEST_H

class  CallbackBase
{
public :
    
virtual   void   operator ()()  const  { };
    
virtual   ~ CallbackBase()  =   0 ;
};

CallbackBase::
~ CallbackBase() { }
template
< typename T >
class  Callback :  public  CallbackBase
{
public :
    typedef 
void  (T:: * F)();
    Callback( T
&  t, F f ) : t_( & t), f_(f) { }
    
void   operator ()()  const  { (t_ ->* f_)(); }
private :
    T
*  t_;
    F  f_;
};

template
< typename T >
Callback
< T >  make_callback( T &  t,  void  (T:: * f) () )
{
    
return  Callback < T > ( t, f );
}

你可能感兴趣的:(我的C++委托类最终版)