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;
}
{
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;
}
{
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类是多分派的。
下载:
https://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 );
}
#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 );
}