委托(delegate)有委托接收方和委托发出方两个实例。委托接收方需要有一个函数实现,然后“拜托”别人调用。委托发出方需要有一个“服务员”接受委托接收方的“委托”请求,并记录调用入口,在非面向对象的时候用的是函数指针,现 在面向对象,需要保存this后调用才行,所以不同的语言用了不同的实现方法。
BCB, 使用关键字__closure
基本上可以解决。
先声明“服务员”能接受什么样的申请:
typedef
BOOL __fastcall(__closure
*FSynchronizationCaller)(SynchronizationManager
*synchronization_manager);
委托发出方,这里用ExitCallers保存调用入口
class
SynchronizationChecker
{
public:
FSynchronizationCaller
ExitCallers;
};
普通赋值语句就可以保存入口,实现“拜托”的工作
ExitCallers=FirstBranch;//FirstBranch的函数与“服务员”对应<
/span>
调用的时候ExitCallers象普通函数一样使用,但是this已经是委托接收方的了。
Delphi更简单, __closure关键字都不用
先声明“服务员”能接受什么样的申请:
type
FSynchronizationCaller = function
(synchronization_manager:TObject):Boolean of object;
后面的做法与BCB类似
这里着重讲VC的<
br>VC6,VC7:参照fast
delegate。但是比它还要快和易懂
首先声明委托通用类,即所有this的通用化
class
GenClass{};
//设置成与BCB类似的形式
#define __Closure
GenClass::
定义模板
template<class T,typename
FunctionType>
class
Closure
{
public:
   
FunctionType Func;
    T
*This;
};
template<typename
FunctionType,typename RetType=void *>
class
Delegate
{
    typedef
Closure<GenClass,FunctionType>
ClosureType;
    ClosureType
*ClosureClass;
public:
   
Delegate(){ClosureClass=0;}
   
~Delegate(){delete
ClosureClass;}
public:
  
    //--------------for no param
function
    template <class
X>
       
inline void bind(X *pthis, void (X::* function_to_bind)())//for void
return function
   
{
       
typedef void
(X::*LocalFunctionType)();
       
typedef Closure<X,LocalFunctionType>
X_ClosureType;
       
X_ClosureType *c=new
X_ClosureType;
       
c->This=pthis;
       
c->Func=function_to_bind;
       
ClosureClass=(ClosureType *)c;
   
}
    template <class
X>
       
inline void bind(X *pthis, RetType (X::* function_to_bind)())//for
other(not void) return function
   
{
       
typedef RetType
(X::*LocalFunctionType)();
       
typedef Closure<X,LocalFunctionType>
X_ClosureType;
       
X_ClosureType *c=new
X_ClosureType;
       
c->This=pthis;
       
c->Func=function_to_bind;
       
ClosureClass=(ClosureType
*)c;
   
}
    inline RetType
operator()()
   
{
       
typedef RetType (GenClass::*LocalFunctionType)();//convert to void to
void*,if it is
appointed
       
return
(ClosureClass->This->*(LocalFunctionType)ClosureClass->Func)();
   
}
  
    //--------------for 1 param
function
    template <class
X,typename
Param1>
       
inline void bind(X *pthis, void (X::* function_to_bind)(Param1))//for
void return function
   
{
       
typedef void
(X::*LocalFunctionType)(Param1);
       
typedef Closure<X,LocalFunctionType>
X_ClosureType;
       
X_ClosureType *c=new
X_ClosureType;
       
c->This=pthis;
       
c->Func=function_to_bind;
       
ClosureClass=(ClosureType *)c;
   
}
    template <class
X,typename
Param1>
       
inline void bind(X *pthis, RetType (X::*
function_to_bind)(Param1))//for other(not void) return
function
   
{
       
typedef RetType
(X::*LocalFunctionType)(Param1);
       
typedef Closure<X,LocalFunctionType>
X_ClosureType;
       
X_ClosureType *c=new
X_ClosureType;
       
c->This=pthis;
       
c->Func=function_to_bind;
       
ClosureClass=(ClosureType *)c;
   
}
    template <typename
Param1>
       
inline RetType operator()(Param1
p1)
   
{
       
typedef RetType (GenClass::*LocalFunctionType)(Param1);//convert to
void to void*,if it is
appointed
       
return
(ClosureClass->This->*(LocalFunctionType)ClosureClass->Func)(p1);
   
}
};
如果有更多的参数需要扩展响应的模板成员函数。
使用的时候
先声
明“服务员”能接受什么样的申请:
typedef
BOOL (__Closure *myfunc)(int a);
typedef
Delegate<myfunc,BOOL>
MyDelegete_t;
#include
<stdio.h>
struct
A
{
  BOOL f(int a){printf("%d",a);return
TRUE;}//与 myfunc对应
};
LRESULT CALLBACK
About(HWND hDlg, UINT message, WPARAM wParam, LPARAM
lParam)
{
  MyDelegete_t
d;
  A a;
 
d.bind(&a,A::f);
 
d(100);
 
............
}
其余部分与BCB类似,不再赘述。
要理解
C++如何用实现委托的,可以参照fastdelegate,和http:
//www.x5dj.com/UserForum/00100079/00009471.shtml
上述源代码从Duceland
Designer
打开例子后生成代码所得,模板这里下载http://duceland.com/Download/VC6.zip
<
br>
C#:
“服务员”能接受什么样的申请是自动完成的,只有保存要函数入口的地方就可以了,这就是进步啊,虽
然不是原创。
public delegate bool
DSynchronizationCaller(SynchronizationManager
synchronization_manager);
其余部分类似,不再赘述。
Java不是很精通,只好这样了
“服务员”是统一的,默认的
保存调用入口比较麻烦
public class
DSynchronizationCaller{
    public Method
m_Method;
    public Object
m_Object;
    public
boolean bind(Class cls,Object object,String
method_name){
   
    m_Object=object;
   
// By obtaining a list of all declared
methods.
       
Method[] methods = cls.getDeclaredMethods();
       
for (int i=0; i<methods.length; i++) {
           
if(methods[i].getName().equals(method_name)){
           
    m_Method=methods[i];
           
    return true;
           
}
       
}
       
return false;
   
}
//调用的时候也不是很自然,用invoke
,参数被转入Object[]数组
    public Object
invoke(SynchronizationManager
synchronization_manager){
   
    try {
       
Object result=m_Method.invoke(m_Object,
new Object[]
{synchronization_manager});
       
    return result;
   
} catch (Exception e)
{System.err.println(e);}
   
    return null;
    }
};
事件通过bind绑定后用invoke执行。



		
		
		

还没有评论,来说两句吧...