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

來源:互聯網
上載者:User
委託(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執行。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.