VC,BCB,C#,Delphi,Java的委托方案

委托(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执行。