在C++實現委託

在C++實現委託
 在前面提到回調了,那麼現在就開始說委託吧。個人是這麼理解委託的,就是一件事你不做或者不能做或者不想做,那麼就委託給別人做,我只調用別人的函數接口就可以了,也就是我要實現一個功能,我只要接口,實際的實現委託給別人,突然有一天我要做的事的邏輯發生了變化,那麼我也不需要更改自己的調用,只需要被委託者更換一下邏輯就可以了。同時,如果在一定的場合下要調用很多相同形式的函數,那麼使用委託將很方便。
在設計模式中狀態模式、策略模式、訪問者模式本質上是在更特殊的場合採用了委託模式。委託也可以接受多個實例方法,你可以向一個委託註冊多個方法。實際上,委託包含了一個方法引用的列表,當委託被調用時,它將順序調用其列表中的方法引用。 
“委託”在C#中是一個語言級特性,C++中是沒有的,那麼我們來實現吧~
 
Method1:成員函數指針加模板
記得在回調函數中我們使用的成員函數指針麼,如果再加上模板將成員函數泛化,天下無敵~
代碼:
[cpp] view plaincopyprint?
01.#include <iostream>   
02.  
03.using namespace std;  
04.   
05.template<typename T>  
06.class A  
07.{  
08.private:  
09.  
10.        typedef int (T::*delegateFun)(int);  
11.  
12.        T* _This;  
13.  
14.        delegateFun _deleGate;  
15.public:      
16.  
17.        A(T * This, delegateFun delegatefun)  
18.        {   
19.  
20.                _This = This;  
21.                _deleGate = delegatefun;  
22.        }  
23.  
24.        int execue(int c)  
25.        {  
26.  
27.                return (_This->*_deleGate)(c);  
28.  
29.        }  
30.};  
31.  
32.   
33.  
34.class B  
35.  
36.{  
37.  
38.public:  
39.  
40.        int FunA(int a) {return a + 10;}  
41.  
42.        int FunB(int a) {return a - 10;}  
43.  
44.        B(){}  
45.  
46.};  
47.  
48.   
49.  
50.void main(void)  
51.{  
52.  
53.        B *objB = new B();  
54.  
55.        A<B>  delegateObj1(objB, (&B::FunA));  
56.        A<B>  delegateObj2(objB, (&B::FunB));  
57.  
58.        cout << delegateObj1.execue(10) <<endl;  
59.        cout << delegateObj2.execue(20) <<endl;  
60.}  
#include <iostream>
using namespace std;
 
template<typename T>
class A
{
private:
        typedef int (T::*delegateFun)(int);
        T* _This;
        delegateFun _deleGate;
public:   
        A(T * This, delegateFun delegatefun)
        {
                _This = This;
                _deleGate = delegatefun;
        }
        int execue(int c)
        {
                return (_This->*_deleGate)(c);
        }
};
 
class B
{
public:
        int FunA(int a) {return a + 10;}
        int FunB(int a) {return a - 10;}
        B(){}
};
 
void main(void)
{
        B *objB = new B();
        A<B>  delegateObj1(objB, (&B::FunA));
        A<B>  delegateObj2(objB, (&B::FunB));
        cout << delegateObj1.execue(10) <<endl;
        cout << delegateObj2.execue(20) <<endl;
}
 
 
Method2:來個純面向對象的方法
代碼:
[cpp] view plaincopyprint?
01.#include <iostream>   
02.  
03.using namespace std;  
04.  
05.   
06.  
07.class EventHandler {  
08.  
09.public:  
10.  
11.        virtual void exec() = 0;  
12.  
13.};  
14.  
15.   
16.  
17.class Event{  
18.  
19.public:  
20.  
21.        void set_handler( EventHandler* h){ _handler = h; }  
22.  
23.        void exec(){_handler->exec();}  
24.  
25.private:  
26.  
27.        EventHandler* _handler;  
28.  
29.};  
30.  
31.   
32.  
33.class MyHandler : public EventHandler {  
34.  
35.public:  
36.  
37.        void exec() { cout << "Handler---" << endl; }  
38.  
39.};  
40.  
41.   
42.  
43.void main(void)  
44.  
45.{  
46.  
47.        Event e;  
48.  
49.        MyHandler h;  
50.  
51.        e.set_handler(&h);  
52.  
53.        e.exec();  
54.  
55.}  
#include <iostream>
using namespace std;
 
class EventHandler {
public:
        virtual void exec() = 0;
};
 
class Event{
public:
        void set_handler( EventHandler* h){ _handler = h; }
        void exec(){_handler->exec();}
private:
        EventHandler* _handler;
};
 
class MyHandler : public EventHandler {
public:
        void exec() { cout << "Handler---" << endl; }
};
 
void main(void)
{
        Event e;
        MyHandler h;
        e.set_handler(&h);
        e.exec();
}
 
 
Method3:使用list進行多調用
代碼是下面博客裏的,大家來感受一下~,這裏主要注重的是註冊的增刪,保存,執行,如果再加上多種回調機制那就更牛了。
http://blog.csdn.net/cambest/archive/2004/04/12/17122.aspx
代碼:
[cpp] view plaincopyprint?
01.#include <list>   
02.  
03.#include <iostream>   
04.  
05.#include <windows.h>   
06.  
07.using namespace std;  
08.  
09.   
10.  
11.typedef unsigned int NativePtr;  
12.  
13.typedef void (* Handler)(char *);  
14.  
15.   
16.  
17.class CDelegate   
18.  
19.{  
20.  
21.private:  
22.  
23.        list<NativePtr> ftns;  
24.  
25.public:  
26.  
27.        void AddFunction(void *);       
28.  
29.        void RemoveFunction(void *);  
30.  
31.        int Invoke(char *);  
32.  
33.        void operator += (void *);  
34.  
35.        void operator -= (void *);  
36.  
37.        int operator ()(char *);  
38.  
39.          
40.  
41.};  
42.  
43.   
44.  
45.void CDelegate::AddFunction(void *ftn)  
46.  
47.{         
48.  
49.        NativePtr np=(NativePtr)ftn;  
50.  
51.        ftns.push_back(np);  
52.  
53.}  
54.  
55.   
56.  
57.void CDelegate::RemoveFunction(void *ftn)  
58.  
59.{  
60.  
61.        NativePtr np=(NativePtr)ftn;  
62.  
63.        ftns.remove(np);  
64.  
65.}  
66.  
67.   
68.  
69.void CDelegate::operator += (void *ftn)  
70.  
71.{         
72.  
73.        this->AddFunction(ftn);   
74.  
75.}  
76.  
77.   
78.  
79.void CDelegate::operator -= (void *ftn)  
80.  
81.{         
82.  
83.        this->RemoveFunction(ftn);        
84.  
85.}  
86.  
87.   
88.  
89.int CDelegate::Invoke(char * pch)  
90.  
91.{         
92.  
93.        Handler handle;   
94.  
95.        list<NativePtr>::iterator itr=ftns.begin();  
96.  
97.        try       
98.  
99.        {  
100.  
101.                for(;itr!=ftns.end();itr++)       
102.  
103.                {         
104.  
105.                        handle=(Handler)*itr;  
106.  
107.                        handle(pch);  
108.  
109.                }  
110.  
111.        }  
112.  
113.        catch(char *)     
114.  
115.        {  
116.  
117.                return 0;  
118.  
119.        }  
120.  
121.        return 1;  
122.  
123.}  
124.  
125.   
126.  
127.int CDelegate::operator ()(char *pch)  
128.  
129.{  
130.  
131.       return Invoke(pch);  
132.  
133.}  
134.  
135.   
136.  
137.void Say1(char *s)  
138.  
139.{  
140.  
141.       cout<<"In Function Say1:   ";  
142.  
143.       cout<<s<<endl;  
144.  
145.}  
146.  
147.   
148.  
149.void Say2(char *s)  
150.  
151.{  
152.  
153.       cout<<"In Function Say2:   ";  
154.  
155.       cout<<s<<endl;  
156.  
157.}  
158.  
159.   
160.  
161.void Say3(char *s)  
162.  
163.{  
164.  
165.       cout<<"In Function Say3:   ";  
166.  
167.       cout<<s<<endl;  
168.  
169.}  
170.  
171.   
172.  
173.void main()  
174.  
175.{  
176.  
177.       CDelegate dlg;  
178.  
179.       dlg.AddFunction(Say1);  
180.  
181.       dlg.AddFunction(Say2);  
182.  
183.       dlg+=Say3;  
184.  
185.   
186.  
187.       int rs=dlg.Invoke("Hello,World!");  
188.  
189.       if(!rs) cout<<"Failed."<<endl;  
190.  
191.   
192.  
193.   
194.  
195.       dlg-=Say2;  
196.  
197.       rs=dlg("The second invoking by CDelegate!");   
198.  
199.       if(!rs) cout<<"Failed."<<endl;  
200.  
201.   
202.  
203.       dlg-=Say1;  
204.  
205.       dlg-=Say3;  
206.  
207.       rs=dlg.Invoke("The Third invoking by CDelegate!");  
208.  
209.       if(!rs) cout<<"Failed."<<endl;  
210.  
211.}  
#include <list>
#include <iostream>
#include <windows.h>
using namespace std;
 
typedef unsigned int NativePtr;
typedef void (* Handler)(char *);
 
class CDelegate
{
private:
        list<NativePtr> ftns;
public:
        void AddFunction(void *);    
        void RemoveFunction(void *);
        int Invoke(char *);
        void operator += (void *);
        void operator -= (void *);
        int operator ()(char *);
       
};
 
void CDelegate::AddFunction(void *ftn)
{      
        NativePtr np=(NativePtr)ftn;
        ftns.push_back(np);
}
 
void CDelegate::RemoveFunction(void *ftn)
{
        NativePtr np=(NativePtr)ftn;
        ftns.remove(np);
}
 
void CDelegate::operator += (void *ftn)
{      
        this->AddFunction(ftn);
}
 
void CDelegate::operator -= (void *ftn)
{      
        this->RemoveFunction(ftn);     
}
 
int CDelegate::Invoke(char * pch)
{      
        Handler handle;
        list<NativePtr>::iterator itr=ftns.begin();
        try    
        {
                for(;itr!=ftns.end();itr++)    
                {      
                        handle=(Handler)*itr;
                        handle(pch);
                }
        }
        catch(char *)  
        {
                return 0;
        }
        return 1;
}
 
int CDelegate::operator ()(char *pch)
{
       return Invoke(pch);
}
 
void Say1(char *s)
{
       cout<<"In Function Say1:   ";
       cout<<s<<endl;
}
 
void Say2(char *s)
{
       cout<<"In Function Say2:   ";
       cout<<s<<endl;
}
 
void Say3(char *s)
{
       cout<<"In Function Say3:   ";
       cout<<s<<endl;
}
 
void main()
{
       CDelegate dlg;
       dlg.AddFunction(Say1);
       dlg.AddFunction(Say2);
       dlg+=Say3;
 
       int rs=dlg.Invoke("Hello,World!");
       if(!rs) cout<<"Failed."<<endl;
 
 
       dlg-=Say2;
       rs=dlg("The second invoking by CDelegate!");
       if(!rs) cout<<"Failed."<<endl;
 
       dlg-=Say1;
       dlg-=Say3;
       rs=dlg.Invoke("The Third invoking by CDelegate!");
       if(!rs) cout<<"Failed."<<endl;
}
 
 
Method4:functor+模板
使用functor是爲了回調的方便,而是用模板就是爲了是委託者和被委託者之間解耦,是被委託者對於委託者透明。
代碼如下:
[cpp] view plaincopyprint?
01.#include <list>   
02.  
03.#include <iostream>   
04.  
05.#include <windows.h>   
06.  
07.using namespace std;  
08.  
09.   
10.  
11.class Add{  
12.  
13.public:  
14.  
15.        Add(int c) {  
16.  
17.                this->c = c;  
18.  
19.        }  
20.  
21.          
22.  
23.        int operator()(int a, int b) {  
24.  
25.                return a + b + c;  
26.  
27.        }  
28.  
29.          
30.  
31.private:  
32.  
33.        int c;  
34.  
35.};  
36.  
37.   
38.  
39.class Mul{  
40.  
41.public:  
42.  
43.        Mul(int c) {  
44.  
45.                this->c = c;  
46.  
47.        }  
48.  
49.          
50.  
51.        int operator()(int a, int b) {  
52.  
53.                return a * b * c;  
54.  
55.        }  
56.  
57.          
58.  
59.private:  
60.  
61.        int c;  
62.  
63.};  
64.  
65.   
66.  
67.template<typename T>  
68.  
69.void Do(T& f, int a, int b) {  
70.  
71.        int r = f(a, b);  
72.  
73.        std::cout << r << std::endl;  
74.  
75.};  
76.  
77.   
78.  
79.void main(void){  
80.  
81.        Add adder(1);  
82.  
83.        Do(adder, 1, 2);   
84.  
85.        Mul multiplier(10);  
86.  
87.        Do(multiplier, 2, 3);  
88.  
89.}  
#include <list>
#include <iostream>
#include <windows.h>
using namespace std;
 
class Add{
public:
        Add(int c) {
                this->c = c;
        }
       
        int operator()(int a, int b) {
                return a + b + c;
        }
       
private:
        int c;
};
 
class Mul{
public:
        Mul(int c) {
                this->c = c;
        }
       
        int operator()(int a, int b) {
                return a * b * c;
        }
       
private:
        int c;
};
 
template<typename T>
void Do(T& f, int a, int b) {
        int r = f(a, b);
        std::cout << r << std::endl;
};
 
void main(void){
        Add adder(1);
        Do(adder, 1, 2);
        Mul multiplier(10);
        Do(multiplier, 2, 3);
}
 
 
Method5:還是functor+模板,但是搞得複雜點
代碼:
[cpp] view plaincopyprint?
01.#include <stdio.h>   
02.  
03.#include <iostream>   
04.  
05.#include <windows.h>   
06.  
07.using namespace std;  
08.  
09.   
10.  
11.template<typename Y, typename X, typename R>     
12.  
13.class FastDelegate     
14.  
15.{     
16.  
17.public:     
18.  
19.    FastDelegate(Y* y, R (X::*Fun)())     
20.  
21.    {     
22.  
23.        m_pPointer = y;     
24.  
25.        m_fun = Fun;     
26.  
27.    }     
28.  
29.          
30.  
31.    R operator()()     
32.  
33.    {     
34.  
35.        return (m_pPointer->*m_fun)();     
36.  
37.    }     
38.  
39.          
40.  
41.    void CallMemerPointer()     
42.  
43.    {     
44.  
45.        (m_pPointer->*m_fun)();     
46.  
47.    }     
48.  
49.protected:     
50.  
51.private:     
52.  
53.    Y*      m_pPointer;     
54.  
55.    typedef R (X::*Fun)();     
56.  
57.    Fun     m_fun;     
58.  
59.};   
60.  
61.   
62.  
63.   
64.  
65.class FuncPointer     
66.  
67.{     
68.  
69.public:     
70.  
71.    int TestFunc1()     
72.  
73.    {     
74.  
75.        printf("call TestFunc1:/r/n");  
76.  
77.                int i = 1;  
78.  
79.                return i;  
80.  
81.    }     
82.  
83.          
84.  
85.    int TestFunc2()     
86.  
87.    {     
88.  
89.        printf("call TestFunc2:/r/n");  
90.  
91.                int i = 2;  
92.  
93.                return i;  
94.  
95.    }     
96.  
97.          
98.  
99.};     
100.  
101.   
102.  
103.template <class X, class Y, class RetType>  
104.  
105.FastDelegate<Y, X, RetType >  
106.  
107.bind(  
108.  
109.  RetType (X::*func)(),  
110.  
111.  Y* y,  
112.  
113.  ...)  
114.  
115.{   
116.  
117. return FastDelegate<Y,X, RetType>(y, func);  
118.  
119.}  
120.  
121.   
122.  
123.   
124.  
125.void main(void)  
126.  
127.{     
128.  
129.    FuncPointer* fp = new FuncPointer();   
130.  
131.        bind(&FuncPointer::TestFunc1, fp).CallMemerPointer();  
132.  
133.        bind(&FuncPointer::TestFunc2, fp).CallMemerPointer();  
134.  
135.   
136.  
137.        bind(&FuncPointer::TestFunc1, fp)();  
138.  
139.        bind(&FuncPointer::TestFunc2, fp)();  
140.  
141.}  
#include <stdio.h>
#include <iostream>
#include <windows.h>
using namespace std;
 
template<typename Y, typename X, typename R>  
class FastDelegate  
{  
public:  
    FastDelegate(Y* y, R (X::*Fun)())  
    {  
        m_pPointer = y;  
        m_fun = Fun;  
    }  
       
    R operator()()  
    {  
        return (m_pPointer->*m_fun)();  
    }  
       
    void CallMemerPointer()  
    {  
        (m_pPointer->*m_fun)();  
    }  
protected:  
private:  
    Y*      m_pPointer;  
    typedef R (X::*Fun)();  
    Fun     m_fun;  
};
 
 
class FuncPointer  
{  
public:  
    int TestFunc1()  
    {  
        printf("call TestFunc1:/r/n");
                int i = 1;
                return i;
    }  
       
    int TestFunc2()  
    {  
        printf("call TestFunc2:/r/n");
                int i = 2;
                return i;
    }  
       
};  
 
template <class X, class Y, class RetType>
FastDelegate<Y, X, RetType >
bind(
  RetType (X::*func)(),
  Y* y,
  ...)
{
 return FastDelegate<Y,X, RetType>(y, func);
}
 
 
void main(void)
{  
    FuncPointer* fp = new FuncPointer();
        bind(&FuncPointer::TestFunc1, fp).CallMemerPointer();
        bind(&FuncPointer::TestFunc2, fp).CallMemerPointer();
 
        bind(&FuncPointer::TestFunc1, fp)();
        bind(&FuncPointer::TestFunc2, fp)();
}
 
PS:此時FuncPointer中的函數不能爲static
從微軟的網站上找到這麼篇文章, 創建到 c + + 成員函數的函數指針,地址: http://support.microsoft.com/kb/94579/zh-cn
給了個實例代碼來看看:
#include <iostream.h>
 
class Data
{
private:
   int y;
   static int x;
 
public:
   void SetData(int value) {y = value; return;};
   int GetData() {return y;};
   static void SSetData(int value) {x = value; return;};
   static int SGetData() {return x;};
};
 
int Data::x = 0;
 
void main(void)
{
   Data mydata, mydata2;
 
   // Initialize pointer.
   void (Data::*pmfnP)(int) = &Data::SetData; // mydata.SetData;
 
   // Initialize static pointer.
   void (*psfnP)(int) = &Data::SSetData;
 
   mydata.SetData(5); // Set initial value for private data.
   cout << "mydata.data = " << mydata.GetData() << endl;
 
   (mydata.*pmfnP)(20); // Call member function through pointer.
   cout << "mydata.data = " << mydata.GetData() << endl;
 
   (mydata2.*pmfnP)(10) ; // Call member function through pointer.
   cout << "mydata2.data = " << mydata2.GetData() << endl;
 
   (*psfnP)(30) ; // Call static member function through pointer.
   cout << "static data = " << Data::SGetData() << endl ;
}
可以看出不一樣的地方來了吧~
 
Method6:成員函數指針+模板+Vector
再來個高級點的,綜合一下,函數指針+模板+Vector。
代碼:
[cpp] view plaincopyprint?
01.#include <iostream>   
02.  
03.#include <vector>   
04.  
05.using namespace std;  
06.  
07.   
08.  
09.class BaseDelegate  
10.  
11.{  
12.  
13.public:  
14.  
15.    virtual void Invoke()=0;  
16.  
17.protected:  
18.  
19.    BaseDelegate()  
20.  
21.    {}  
22.  
23.    ~BaseDelegate()  
24.  
25.    {}  
26.  
27.};  
28.  
29.   
30.  
31.class NonTypeDelegate : public BaseDelegate  
32.  
33.{  
34.  
35.public:  
36.  
37.    void Invoke();  
38.  
39.    NonTypeDelegate(void (*pfn)(int),int iParam);  
40.  
41.    virtual ~NonTypeDelegate(){}  
42.  
43.private:  
44.  
45.    void (*m_pfn)(int);  
46.  
47.    int m_iParam;  
48.  
49.};  
50.  
51.   
52.  
53.NonTypeDelegate::NonTypeDelegate(void (*pfn)(int),  
54.  
55.                                 int iParam):m_pfn(pfn),  
56.  
57.                                 m_iParam(iParam)  
58.  
59.{  
60.  
61.}  
62.  
63.void NonTypeDelegate::Invoke()  
64.  
65.{  
66.  
67.    cout << "NonTypeDelegate Invoke/r/n";  
68.  
69.    m_pfn(m_iParam);  
70.  
71.}  
72.  
73.   
74.  
75.template <typename T>  
76.  
77.class TypeDelegate : public BaseDelegate  
78.  
79.{  
80.  
81.public:  
82.  
83.    void Invoke();  
84.  
85.    TypeDelegate(T &t, void (T::*pfn)(int), int iParam);  
86.  
87.    ~TypeDelegate(){}  
88.  
89.private:  
90.  
91.    T m_t;  
92.  
93.    void (T::*m_pfn)(int);  
94.  
95.    int m_iParam;  
96.  
97.};  
98.  
99.   
100.  
101.template<typename T>  
102.  
103.TypeDelegate<T>::TypeDelegate(T &t,  
104.  
105.                              void (T::*pfn)(int),  
106.  
107.                              int iParam):m_t(t),  
108.  
109.                              m_pfn(pfn),  
110.  
111.                              m_iParam(iParam)  
112.  
113.{  
114.  
115.}  
116.  
117.   
118.  
119.template<typename T>  
120.  
121.void TypeDelegate<T>::Invoke()  
122.  
123.{  
124.  
125.    cout << "TypeDelegate Invoke/r/n";  
126.  
127.    (m_t.*m_pfn)(m_iParam);  
128.  
129.}  
130.  
131.void Test(int iParam)  
132.  
133.{  
134.  
135.    cout << "Test Invoked/r/n";  
136.  
137.}  
138.  
139.   
140.  
141.   
142.  
143.class A  
144.  
145.{  
146.  
147.public:  
148.  
149.    void Test(int iParam)  
150.  
151.    {  
152.  
153.        cout << "A::Test Invoked/r/n";  
154.  
155.    }  
156.  
157.};  
158.  
159.   
160.  
161.class B  
162.  
163.{  
164.  
165.public:  
166.  
167.        static void Test(int iParam)  
168.  
169.        {  
170.  
171.                cout << "B::Test Invoked/r/n";  
172.  
173.        }  
174.  
175.};  
176.  
177.   
178.  
179.int main(int argc, char* argv[])  
180.  
181.{  
182.  
183.    NonTypeDelegate nTDelegate(Test,1);  
184.  
185.        NonTypeDelegate nTSDelegate(B::Test,1);  
186.  
187.    A a;  
188.  
189.    TypeDelegate<A> tDelegate(a,&A::Test,2);  
190.  
191.    vector<BaseDelegate*> vecpDelegate;  
192.  
193.    vecpDelegate.push_back(&nTDelegate);  
194.  
195.    vecpDelegate.push_back(&tDelegate);  
196.  
197.        vecpDelegate.push_back(&nTSDelegate);  
198.  
199.      
200.  
201.    for (vector<BaseDelegate*>::const_iterator kItr=vecpDelegate.begin();/  
202.  
203.              kItr!=vecpDelegate.end();  ++kItr)  
204.  
205.    {  
206.  
207.        (*kItr)->Invoke();  
208.  
209.    }  
210.  
211.    return 0;  
212.  
213.}  
#include <iostream>
#include <vector>
using namespace std;
 
class BaseDelegate
{
public:
    virtual void Invoke()=0;
protected:
    BaseDelegate()
    {}
    ~BaseDelegate()
    {}
};
 
class NonTypeDelegate : public BaseDelegate
{
public:
    void Invoke();
    NonTypeDelegate(void (*pfn)(int),int iParam);
    virtual ~NonTypeDelegate(){}
private:
    void (*m_pfn)(int);
    int m_iParam;
};
 
NonTypeDelegate::NonTypeDelegate(void (*pfn)(int),
                                 int iParam):m_pfn(pfn),
                                 m_iParam(iParam)
{
}
void NonTypeDelegate::Invoke()
{
    cout << "NonTypeDelegate Invoke/r/n";
    m_pfn(m_iParam);
}
 
template <typename T>
class TypeDelegate : public BaseDelegate
{
public:
    void Invoke();
    TypeDelegate(T &t, void (T::*pfn)(int), int iParam);
    ~TypeDelegate(){}
private:
    T m_t;
    void (T::*m_pfn)(int);
    int m_iParam;
};
 
template<typename T>
TypeDelegate<T>::TypeDelegate(T &t,
                              void (T::*pfn)(int),
                              int iParam):m_t(t),
                              m_pfn(pfn),
                              m_iParam(iParam)
{
}
 
template<typename T>
void TypeDelegate<T>::Invoke()
{
    cout << "TypeDelegate Invoke/r/n";
    (m_t.*m_pfn)(m_iParam);
}
void Test(int iParam)
{
    cout << "Test Invoked/r/n";
}
 
 
class A
{
public:
    void Test(int iParam)
    {
        cout << "A::Test Invoked/r/n";
    }
};
 
class B
{
public:
        static void Test(int iParam)
        {
                cout << "B::Test Invoked/r/n";
        }
};
 
int main(int argc, char* argv[])
{
    NonTypeDelegate nTDelegate(Test,1);
        NonTypeDelegate nTSDelegate(B::Test,1);
    A a;
    TypeDelegate<A> tDelegate(a,&A::Test,2);
    vector<BaseDelegate*> vecpDelegate;
    vecpDelegate.push_back(&nTDelegate);
    vecpDelegate.push_back(&tDelegate);
        vecpDelegate.push_back(&nTSDelegate);
   
    for (vector<BaseDelegate*>::const_iterator kItr=vecpDelegate.begin();/
              kItr!=vecpDelegate.end();  ++kItr)
    {
        (*kItr)->Invoke();
    }
    return 0;
}
 
可以參考~
 
Method7:超級大牛法,二進制層面抽象泛化註冊事件
在實現委託的過程中,無礙乎一下的過程:
委託器
 
事件器
 
 
 

其中事件器封裝實際的調用過程,而委託器負責響應我們的外部調用,委託器記錄了註冊的事件器並能夠相應的增刪操作,在響應外部調用時可以遍歷事件器並進行調用,事件器需要向委託器進行註冊。
看看下面一位大牛實現的代碼吧,超級牛,注意,這個代碼使用的是VS2008,VC6可能會有問題啊。
[cpp] view plaincopyprint?
01.#include <stdio.h>   
02.  
03.#include <map>   
04.  
05.using namespace std;  
06.  
07.   
08.  
09.typedef unsigned int uint;  
10.  
11.typedef unsigned char uchar;  
12.  
13./////////////////////////////////////////////////////////////////////////////////   
14.  
15./// /class FuncCache   
16.  
17./// /brief 函數對 象寄存器   
18.  
19./////////////////////////////////////////////////////////////////////////////////   
20.  
21.template <typename ReturnType>  
22.  
23.class FuncCache  
24.  
25.{  
26.  
27.     static const int SIZE = 48;  
28.  
29.     typedef ReturnType (*func_caller)(FuncCache*);  
30.  
31.   
32.  
33.     /// /class MemberFuncAssist   
34.  
35.     /// /brief 對象成員 函數寄存器的輔 助器   
36.  
37.     class FuncCacheAssist  
38.  
39.     {  
40.  
41.     public:  
42.  
43.         /// /brief 構造函數,初始化。   
44.  
45.         FuncCacheAssist(FuncCache* pFunc)  
46.  
47.         {  
48.  
49.              m_Size = 0;  
50.  
51.              m_pFunc = pFunc;  
52.  
53.              // 讀取用偏移必須 ?位   
54.  
55.              m_pFunc->m_Cur = 0;  
56.  
57.         }  
58.  
59.         /// /brief 析構 函數。   
60.  
61.         ~FuncCacheAssist(void)  
62.  
63.         {  
64.  
65.              // 彈出以前壓 入的參數   
66.  
67.              if (m_Size > 0)  
68.  
69.                   m_pFunc->Pop(m_Size);  
70.  
71.         }  
72.  
73.         /// /brief 壓入指定大小的數據。   
74.  
75.         uint Push(const void* pData, uint size)  
76.  
77.         {  
78.  
79.              m_Size += size;  
80.  
81.              return m_pFunc->Push(pData, size);  
82.  
83.         }  
84.  
85.   
86.  
87.         /// 壓入參數的大小   
88.  
89.         int                m_Size;  
90.  
91.         /// 對象成員 函數寄存器   
92.  
93.         FuncCache*         m_pFunc;  
94.  
95.     };  
96.  
97.   
98.  
99.public:  
100.  
101.     /// /brief 構造函數,初始化。   
102.  
103.     FuncCache(func_caller func)  
104.  
105.     {  
106.  
107.         m_Size = 0;  
108.  
109.         m_Cur = 0;  
110.  
111.         m_Func = func;  
112.  
113.     }  
114.  
115.     /// /brief 壓入指定大小的數據。   
116.  
117.     uint     Push(const void* pData, uint size)  
118.  
119.     {  
120.  
121.         size = (size <= SIZE - m_Size)? size : (SIZE - m_Size);  
122.  
123.         memcpy(m_Buffer + m_Size, pData, size);  
124.  
125.         m_Size += size;  
126.  
127.         return size;  
128.  
129.     }  
130.  
131.     /// /brief 彈出指定大小的數據。   
132.  
133.     uint      Pop(uint size)  
134.  
135.     {  
136.  
137.         size = (size < m_Size)? size : m_Size;  
138.  
139.         m_Size -= size;  
140.  
141.         return size;  
142.  
143.     }  
144.  
145.     /// /brief 讀取指定大小的數據,返回指針 。   
146.  
147.     void*         Read(uint size)  
148.  
149.     {  
150.  
151.         m_Cur += size;  
152.  
153.         return (m_Buffer + m_Cur - size);  
154.  
155.     }  
156.  
157.     /// /brief 執行一個參數的函數。   
158.  
159.     ReturnType    Execute(const void* pData)  
160.  
161.     {  
162.  
163.         // 用輔 助結 ?控制   
164.  
165.         FuncCacheAssist assist(this);  
166.  
167.         // 壓入參數   
168.  
169.         assist.Push(&pData, sizeof(void*));  
170.  
171.         // 執行函數   
172.  
173.         return m_Func(this);  
174.  
175.     }  
176.  
177.   
178.  
179.protected:  
180.  
181.     /// 對象,函數,參數指針 的緩 衝區   
182.  
183.     uchar         m_Buffer[SIZE];  
184.  
185.     /// 緩衝區大小   
186.  
187.     uint          m_Size;  
188.  
189.     /// 緩衝區讀 取用的偏移   
190.  
191.     uint          m_Cur;  
192.  
193.     /// 操作函數的指針      func_caller   m_Func;   
194.  
195.};  
196.  
197.   
198.  
199.   
200.  
201./////////////////////////////////////////////////////////////////////////////////   
202.  
203./// /class MFuncCall_1   
204.  
205./// /brief 一個參數的成員 函數執 行體   
206.  
207./////////////////////////////////////////////////////////////////////////////////   
208.  
209.template <typename ReturnType, typename Caller, typename Func, typename ParamType>  
210.  
211.class MFuncCall_1  
212.  
213.{  
214.  
215.public:  
216.  
217.     /// /brief 執行一個參數的成員 函數。   
218.  
219.     static ReturnType MFuncCall(FuncCache<ReturnType>* pMFunc)  
220.  
221.     {  
222.  
223.         // 獲得對 象指針          Caller* pCaller = *(Caller**)pMFunc->Read(sizeof(Caller*));   
224.  
225.         // 獲得成員 函數指針          Func func = *(Func*)pMFunc->Read(sizeof(Func));   
226.  
227.         // 獲得參數的指針          ParamType* pData = *(ParamType**)pMFunc->Read(sizeof(ParamType*));   
228.  
229.         // 執行成員 函數   
230.  
231.         return (pCaller->*func)(*pData);  
232.  
233.     }  
234.  
235.};  
236.  
237.   
238.  
239.   
240.  
241./////////////////////////////////////////////////////////////////////////////////   
242.  
243./// /class L_SignalRoot   
244.  
245./// /brief 類型檢 ?嚴 格的事件委託器基類 /////////////////////////////////////////////////////////////////////////////////   
246.  
247.template <typename ReturnType>  
248.  
249.class L_SignalRoot  
250.  
251.{  
252.  
253.public:  
254.  
255.     /// /brief 指定事件名,卸載 指定對 象的事件委託器。   
256.  
257.     template <typename Caller>  
258.  
259.     void     MFuncUnregister(Caller* pCaller)  
260.  
261.     {  
262.  
263.         func_map& func_list = m_MemberFuncMap;  
264.  
265.         func_map::iterator it = func_list.find(pCaller);  
266.  
267.         if (it != func_list.end())  
268.  
269.              func_list.erase(it);  
270.  
271.     }  
272.  
273.     /// /brief 清空所有事件委託器。   
274.  
275.     void     MFuncClear(void)  
276.  
277.     {  
278.  
279.         m_MemberFuncMap.clear();  
280.  
281.     }  
282.  
283.   
284.  
285.protected:  
286.  
287.     typedef map< void*, FuncCache<ReturnType> > func_map;  
288.  
289.     /// 事件名和綁 定的事件委託器的列表   
290.  
291.     func_map m_MemberFuncMap;  
292.  
293.};  
294.  
295.   
296.  
297.   
298.  
299./////////////////////////////////////////////////////////////////////////////////   
300.  
301./// /class L_Signal_1   
302.  
303./// /brief 類型檢 ?嚴 格,一個參數的事件委託器   
304.  
305./////////////////////////////////////////////////////////////////////////////////   
306.  
307.template <typename ReturnType, typename ParamType>  
308.  
309.class L_Signal_1 : public L_SignalRoot<ReturnType>  
310.  
311.{  
312.  
313.public:  
314.  
315.     /// /brief 指定事件名,註冊對 ?的一個參數的事件委託器。   
316.  
317.     template <typename Caller, typename Func>  
318.  
319.     void     MFuncRegister(Caller* pCaller, Func func)  
320.  
321.     {  
322.  
323.         // 指定專 ?處 理一個參數的函數執 行體   
324.  
325.         FuncCache<ReturnType> mfunc(MFuncCall_1<ReturnType, Caller, Func, ParamType>::MFuncCall);  
326.  
327.         // 壓入對 象和函數   
328.  
329.         mfunc.Push(&pCaller, sizeof(Caller*));  
330.  
331.         mfunc.Push(&func, sizeof(Func));  
332.  
333.         // 添加到事件委託器列表   
334.  
335.         m_MemberFuncMap.insert(make_pair(pCaller, mfunc));  
336.  
337.     }  
338.  
339.     /// /brief 指定事件名,調 用其對 ?的一個參數的事件委託器。   
340.  
341.     ReturnType    MFuncCall(const ParamType& data)  
342.  
343.     {   
344.  
345.         // 清空返回值          ReturnType result;   
346.  
347.         memset(&result, 0, sizeof(result));  
348.  
349.         // 對於所有委託器,調 用註冊的函數   
350.  
351.         func_map::iterator it = m_MemberFuncMap.begin();  
352.  
353.         while (it != m_MemberFuncMap.end())  
354.  
355.         {  
356.  
357.              result = it->second.Execute(&data);  
358.  
359.              ++it;  
360.  
361.         }  
362.  
363.         return result;  
364.  
365.     }  
366.  
367.};  
368.  
369.   
370.  
371.   
372.  
373.class EventCallerA  
374.  
375.{  
376.  
377.public:  
378.  
379.     bool Do(int event_id)  
380.  
381.     {  
382.  
383.         printf("EventCallerA do event %d./r/n", event_id);  
384.  
385.         return true;  
386.  
387.     }  
388.  
389.};  
390.  
391.class EventCallerB  
392.  
393.{  
394.  
395.public:  
396.  
397.     bool Run(int event_id)  
398.  
399.     {  
400.  
401.         printf("EventCallerB run event %d./r/n", event_id);  
402.  
403.         return true;  
404.  
405.     }  
406.  
407.};  
408.  
409.   
410.  
411.void main()  
412.  
413.{  
414.  
415.     // 申明返回值 是bool類型,參數是int類型,單 參數的事件器   
416.  
417.     L_Signal_1<bool, int> signal;  
418.  
419.     EventCallerA callerA;   
420.  
421.     EventCallerB callerB;  
422.  
423.// 註冊委託器並調 用事件   
424.  
425.     signal.MFuncRegister(&callerA, &EventCallerA::Do);   
426.  
427.     signal.MFuncRegister(&callerB, &EventCallerB::Run);  
428.  
429.     signal.MFuncCall(1);  
430.  
431.}  
#include <stdio.h>
#include <map>
using namespace std;
 
typedef unsigned int uint;
typedef unsigned char uchar;
/////////////////////////////////////////////////////////////////////////////////
/// /class FuncCache
/// /brief 函數對 象寄存器
/////////////////////////////////////////////////////////////////////////////////
template <typename ReturnType>
class FuncCache
{
     static const int SIZE = 48;
     typedef ReturnType (*func_caller)(FuncCache*);
 
     /// /class MemberFuncAssist
     /// /brief 對象成員 函數寄存器的輔 助器
     class FuncCacheAssist
     {
     public:
         /// /brief 構造函數,初始化。
         FuncCacheAssist(FuncCache* pFunc)
         {
              m_Size = 0;
              m_pFunc = pFunc;
              // 讀取用偏移必須 ?位
              m_pFunc->m_Cur = 0;
         }
         /// /brief 析構 函數。
         ~FuncCacheAssist(void)
         {
              // 彈出以前壓 入的參數
              if (m_Size > 0)
                   m_pFunc->Pop(m_Size);
         }
         /// /brief 壓入指定大小的數據。
         uint Push(const void* pData, uint size)
         {
              m_Size += size;
              return m_pFunc->Push(pData, size);
         }
 
         /// 壓入參數的大小
         int                m_Size;
         /// 對象成員 函數寄存器
         FuncCache*         m_pFunc;
     };
 
public:
     /// /brief 構造函數,初始化。
     FuncCache(func_caller func)
     {
         m_Size = 0;
         m_Cur = 0;
         m_Func = func;
     }
     /// /brief 壓入指定大小的數據。
     uint     Push(const void* pData, uint size)
     {
         size = (size <= SIZE - m_Size)? size : (SIZE - m_Size);
         memcpy(m_Buffer + m_Size, pData, size);
         m_Size += size;
         return size;
     }
     /// /brief 彈出指定大小的數據。
     uint      Pop(uint size)
     {
         size = (size < m_Size)? size : m_Size;
         m_Size -= size;
         return size;
     }
     /// /brief 讀取指定大小的數據,返回指針 。
     void*         Read(uint size)
     {
         m_Cur += size;
         return (m_Buffer + m_Cur - size);
     }
     /// /brief 執行一個參數的函數。
     ReturnType    Execute(const void* pData)
     {
         // 用輔 助結 ?控制
         FuncCacheAssist assist(this);
         // 壓入參數
         assist.Push(&pData, sizeof(void*));
         // 執行函數
         return m_Func(this);
     }
 
protected:
     /// 對象,函數,參數指針 的緩 衝區
     uchar         m_Buffer[SIZE];
     /// 緩衝區大小
     uint          m_Size;
     /// 緩衝區讀 取用的偏移
     uint          m_Cur;
     /// 操作函數的指針      func_caller   m_Func;
};
 
 
/////////////////////////////////////////////////////////////////////////////////
/// /class MFuncCall_1
/// /brief 一個參數的成員 函數執 行體
/////////////////////////////////////////////////////////////////////////////////
template <typename ReturnType, typename Caller, typename Func, typename ParamType>
class MFuncCall_1
{
public:
     /// /brief 執行一個參數的成員 函數。
     static ReturnType MFuncCall(FuncCache<ReturnType>* pMFunc)
     {
         // 獲得對 象指針          Caller* pCaller = *(Caller**)pMFunc->Read(sizeof(Caller*));
         // 獲得成員 函數指針          Func func = *(Func*)pMFunc->Read(sizeof(Func));
         // 獲得參數的指針          ParamType* pData = *(ParamType**)pMFunc->Read(sizeof(ParamType*));
         // 執行成員 函數
         return (pCaller->*func)(*pData);
     }
};
 
 
/////////////////////////////////////////////////////////////////////////////////
/// /class L_SignalRoot
/// /brief 類型檢 ?嚴 格的事件委託器基類 /////////////////////////////////////////////////////////////////////////////////
template <typename ReturnType>
class L_SignalRoot
{
public:
     /// /brief 指定事件名,卸載 指定對 象的事件委託器。
     template <typename Caller>
     void     MFuncUnregister(Caller* pCaller)
     {
         func_map& func_list = m_MemberFuncMap;
         func_map::iterator it = func_list.find(pCaller);
         if (it != func_list.end())
              func_list.erase(it);
     }
     /// /brief 清空所有事件委託器。
     void     MFuncClear(void)
     {
         m_MemberFuncMap.clear();
     }
 
protected:
     typedef map< void*, FuncCache<ReturnType> > func_map;
     /// 事件名和綁 定的事件委託器的列表
     func_map m_MemberFuncMap;
};
 
 
/////////////////////////////////////////////////////////////////////////////////
/// /class L_Signal_1
/// /brief 類型檢 ?嚴 格,一個參數的事件委託器
/////////////////////////////////////////////////////////////////////////////////
template <typename ReturnType, typename ParamType>
class L_Signal_1 : public L_SignalRoot<ReturnType>
{
public:
     /// /brief 指定事件名,註冊對 ?的一個參數的事件委託器。
     template <typename Caller, typename Func>
     void     MFuncRegister(Caller* pCaller, Func func)
     {
         // 指定專 ?處 理一個參數的函數執 行體
         FuncCache<ReturnType> mfunc(MFuncCall_1<ReturnType, Caller, Func, ParamType>::MFuncCall);
         // 壓入對 象和函數
         mfunc.Push(&pCaller, sizeof(Caller*));
         mfunc.Push(&func, sizeof(Func));
         // 添加到事件委託器列表
         m_MemberFuncMap.insert(make_pair(pCaller, mfunc));
     }
     /// /brief 指定事件名,調 用其對 ?的一個參數的事件委託器。
     ReturnType    MFuncCall(const ParamType& data)
     {
         // 清空返回值          ReturnType result;
         memset(&result, 0, sizeof(result));
         // 對於所有委託器,調 用註冊的函數
         func_map::iterator it = m_MemberFuncMap.begin();
         while (it != m_MemberFuncMap.end())
         {
              result = it->second.Execute(&data);
              ++it;
         }
         return result;
     }
};
 
 
class EventCallerA
{
public:
     bool Do(int event_id)
     {
         printf("EventCallerA do event %d./r/n", event_id);
         return true;
     }
};
class EventCallerB
{
public:
     bool Run(int event_id)
     {
         printf("EventCallerB run event %d./r/n", event_id);
         return true;
     }
};
 
void main()
{
     // 申明返回值 是bool類型,參數是int類型,單 參數的事件器
     L_Signal_1<bool, int> signal;
     EventCallerA callerA;
     EventCallerB callerB;
// 註冊委託器並調 用事件
     signal.MFuncRegister(&callerA, &EventCallerA::Do);
     signal.MFuncRegister(&callerB, &EventCallerB::Run);
     signal.MFuncCall(1);
}
 
 
Method8:使用FastDelegate
FastDelegate是實現好的開源庫,如果有時間的話看看下面這個,很不錯~
 
好了,到這裏爲止,其實把我們前面的回調做好封裝,就可以實現不錯的委託,更新更好的方法還需要一點一滴的努力~
委託,To be, or not to be...

發佈了24 篇原創文章 · 獲贊 12 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章