• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 32  文章 - 94  trackbacks - 0
            <2009年7月>
            2829301234
            567891011
            12131415161718
            19202122232425
            2627282930311
            2345678

            常用鏈接

            留言簿(8)

            隨筆分類

            隨筆檔案

            好友連接

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            寫這個程序前,參考過vczh的VL_Data_Event,也看過何詠的,寫的目的:第一主要是想熟練c++的模板;第二是重復發明車輪,也擁有自己的事件類了~~。

            上大學開始接觸編程,一開始便學習C++,但是教科書對模板的介紹都比較少,當時連比較基礎的C++都學得一塌糊涂,更不用說模板了。
            現在工作任務完成,有點空閑時間看《C++templates》,看到現在終于能寫點像樣的C++模板了。

            目前事件類的封裝還沒有對0--5個參數模板的特化,這里只貼出具有6個參數的事件類代碼:
              1#pragma once
              2#include <list>
              3using namespace std;
              4
              5//函數調用類抽象接口
              6template<typename param1,typename param2,typename param3,typename param4,typename param5,typename param6>
              7class CY_FunctionInterface
              8{
              9public:
             10    virtual void* GetClassHandler()=0;
             11    virtual void* GetFunHandler()=0;
             12    virtual void Invoke(param1 p1,param2 p2,param3 p3,param4 p4,param5 p5,param6 p6)=0;
             13}
            ;
             14
             15
             16//全局函數調用類
             17template<typename param1,typename param2,typename param3,typename param4,typename param5,typename param6>
             18class CY_GolobalFunction:public CY_FunctionInterface<param1,param2,param3,param4,param5,param6>
             19{
             20public:
             21    typedef void(*T_HANDLER)(param1 ,param2 ,param3 ,param4 ,param5 ,param6);
             22protected:
             23    union
             24    {
             25        T_HANDLER FuncHandler;
             26        void*   pFPointer;
             27    }
            ;
             28    
             29public:   
             30    CY_GolobalFunction(T_HANDLER f)
             31    {
             32        FuncHandler=f;
             33    }

             34    void *GetClassHandler()
             35    {
             36        return 0;
             37    }

             38    void *GetFunHandler()
             39    {
             40        return pFPointer;
             41    }

             42    void Invoke(param1 p1,param2 p2,param3 p3,param4 p4,param5 p5,param6 p6)
             43    {
             44        (*FuncHandler)(p1,p2,p3,p4,p5,p6);
             45    }

             46}
            ;
             47
             48//成員函數調用類
             49template<typename Class,typename param1,typename param2,typename param3,typename param4,typename param5,typename param6>
             50class CY_MemberFunction:public CY_FunctionInterface<param1,param2,param3,param4,param5,param6>
             51{
             52public:
             53    typedef void(Class::*T_HANDLER)(param1,param2,param3,param4,param5,param6);
             54protected:
             55    union
             56    {
             57        T_HANDLER FuncHandler;
             58        void *  pFPointer;
             59    }
            ;
             60    union
             61    {
             62        Class *OwnClassHandler;
             63        void * pCPointer;
             64    }
            ;
             65    
             66public:
             67    CY_MemberFunction(Class *pClass,T_HANDLER f)
             68    {
             69        OwnClassHandler=pClass;
             70        FuncHandler=f;
             71    }

             72    void *GetClassHandler()
             73    {
             74        return pCPointer;
             75    }

             76    void *GetFunHandler()
             77    {
             78        return pFPointer;
             79    }

             80    void Invoke(param1 p1,param2 p2,param3 p3,param4 p4,param5 p5,param6 p6)
             81    {
             82        (OwnClassHandler->*FuncHandler)(p1,p2,p3,p4,p5,p6);
             83    }

             84}
            ;
             85
             86
             87//事件封裝
             88template<typename param1,typename param2,typename param3,typename param4,typename param5,typename param6>
             89class CY_Event
             90{
             91protected:
             92    typedef list< CY_FunctionInterface<param1,param2,param3,param4,param5,param6>*> T_FUNCTIONLIST;
             93    typedef typename T_FUNCTIONLIST::iterator T_FUNCTION_ITERATOR;
             94
             95    T_FUNCTIONLIST FunctionList;
             96
             97private:
             98    T_FUNCTION_ITERATOR Find(CY_FunctionInterface<param1,param2,param3,param4,param5,param6>* target)
             99    {
            100        void *temp1=target->GetClassHandler();
            101        void *temp2=target->GetFunHandler();
            102        T_FUNCTION_ITERATOR i=FunctionList.begin();
            103        for (;i!=FunctionList.end();i++)
            104        {
            105            if (temp1==(*i)->GetClassHandler()  &&  temp2==(*i)->GetFunHandler())
            106            {
            107                break;
            108            }

            109        }

            110        return i;
            111    }

            112public:
            113    inline void Invoke(param1 p1,param2 p2,param3 p3,param4 p4,param5 p5,param6 p6)
            114    {
            115        T_FUNCTION_ITERATOR i=FunctionList.begin();
            116        for (;i!=FunctionList.end();i++)
            117        {
            118            (*i)->Invoke(p1,p2,p3,p4,p5,p6);
            119        }

            120    }

            121
            122    void Bind(typename CY_GolobalFunction<param1,param2,param3,param4,param5,param6>::T_HANDLER gFuncHandle)
            123    {
            124        CY_GolobalFunction<param1,param2,param3,param4,param5,param6>*addone=new CY_GolobalFunction<param1,param2,param3,param4,param5,param6>(gFuncHandle);
            125        if(Find(addone)!=FunctionList.end())//已經存在了,就不需要添加
            126            delete addone;//刪除臨時的new對象
            127        else
            128            FunctionList.push_back(addone);
            129    }

            130    void UnBind(typename CY_GolobalFunction<param1,param2,param3,param4,param5,param6>::T_HANDLER gFuncHandle)
            131    {
            132        CY_GolobalFunction<param1,param2,param3,param4,param5,param6>*delone=new CY_GolobalFunction<param1,param2,param3,param4,param5,param6>(gFuncHandle);
            133        T_FUNCTION_ITERATOR delnode=Find(delone);
            134        if (delnode!=FunctionList.end())//存在,刪除節點和指針
            135        {
            136            delete (*delnode);
            137            FunctionList.erase(delnode);
            138        }

            139        delete delone;//刪除臨時的new對象
            140    }

            141    template<typename Class>
            142    void Bind(Class *classHandle,typename CY_MemberFunction<Class,param1,param2,param3,param4,param5,param6>::T_HANDLER mFuncHandle)
            143    {
            144        CY_MemberFunction<Class,param1,param2,param3,param4,param5,param6>*addone=new CY_MemberFunction<Class,param1,param2,param3,param4,param5,param6>(classHandle,mFuncHandle);
            145        if (Find(addone)!=FunctionList.end())//已經存在
            146            delete addone;//刪除臨時的new對象
            147        else
            148            FunctionList.push_back(addone);
            149    }

            150    template<typename Class>
            151    void UnBind(Class *classHandle,typename CY_MemberFunction<Class,param1,param2,param3,param4,param5,param6>::T_HANDLER mFuncHandle)
            152    {
            153        CY_MemberFunction<Class,param1,param2,param3,param4,param5,param6>*delone=new CY_MemberFunction<Class,param1,param2,param3,param4,param5,param6>(classHandle,mFuncHandle);
            154        T_FUNCTION_ITERATOR delnode=Find(delone);
            155        if (delnode!=FunctionList.end())//存在,刪除節點和指針
            156        {
            157            delete (*delnode);
            158            FunctionList.erase(delnode);
            159        }

            160        delete delone;//刪除臨時的new對象
            161    }

            162    void operator()(param1 p1,param2 p2,param3 p3,param4 p4,param5 p5,param6 p6)
            163    {
            164        Invoke(p1,p2,p3,p4,p5,p6);
            165    }

            166    ~CY_Event()
            167    {
            168        T_FUNCTION_ITERATOR i=FunctionList.begin();
            169        for (;i!=FunctionList.end();i++)
            170        {
            171            delete (*i);
            172        }

            173    }

            174}
            ;

            測試代碼:
             1#define _CRTDBG_MAP_ALLOC  
             2#include<stdlib.h>  
             3
             4#include<crtdbg.h>
             5
             6#include <iostream>
             7#include "Event.h"
             8
             9using namespace std;
            10
            11class MyClass
            12{
            13public:
            14    void func(int a1,int a2,int a3,int a4,int a5,int a6)
            15    {
            16        cout<<"class func!!"<<endl;
            17        cout<<a1<<endl;
            18        cout<<a2<<endl;
            19        cout<<a3<<endl;
            20        cout<<a4<<endl;
            21        cout<<a5<<endl;
            22        cout<<a6<<endl;
            23        cout<<"class func end-----!!"<<endl;
            24    }

            25}
            ;
            26void gfunc(int a1,int a2,int a3,int a4,int a5,int a6)
            27{
            28    cout<<"global func!!"<<endl;
            29    cout<<a1<<endl;
            30    cout<<a2<<endl;
            31    cout<<a3<<endl;
            32    cout<<a4<<endl;
            33    cout<<a5<<endl;
            34    cout<<a6<<endl;
            35    cout<<"global func end------!!"<<endl;
            36}

            37
            38int main()
            39{
            40    MyClass class1;
            41
            42    CY_Event<int,int,int,int,int,int> *eve;
            43
            44    eve=new CY_Event<int,int,int,int,int,int>;
            45
            46    eve->Bind(&gfunc);
            47    eve->Bind(&class1,&MyClass::func);
            48
            49    cout<<"invoking"<<endl;
            50    eve->Invoke(1,2,3,4,5,6);
            51    eve->UnBind(&class1,&MyClass::func);
            52    cout<<"-------------after unBind-------------"<<endl;
            53    eve->Invoke(6,5,4,3,2,1);
            54
            55    delete eve;
            56
            57    int a;
            58    cin>>a;
            59
            60    _CrtDumpMemoryLeaks(); 
            61}
            運行結果:

            posted on 2009-07-25 14:40 陳昱(CY) 閱讀(1919) 評論(6)  編輯 收藏 引用 所屬分類: C++

            FeedBack:
            # re: 實現事件的封裝(類似C#的 delegate) 2009-07-25 15:48 99讀書人
            受益了~~~  回復  更多評論
              
            # re: 實現事件的封裝(類似C#的 delegate) 2009-07-25 19:35 cyberamoeba
            hold a candle to the sun  回復  更多評論
              
            # re: 實現事件的封裝(類似C#的 delegate) 2009-07-25 19:37 cyberamoeba
            Sorry, I made a mistake. My previous comment is wrong.  回復  更多評論
              
            # re: 實現事件的封裝(類似C#的 delegate) 2009-07-25 21:08 legendlee
            這種基于模板的多路委托實現多如牛毛,我也剛寫了一個,跟你這個基本差不多。我有幾個問題:
            1成員函數和全局函數封裝進統一模型,這個我也是這么做的,但是我沒想出來這樣有什么用。

            2個人覺得CY_FunctionInterface及其子類應該是除了CY_Event之外都不應該看到的,應該設計成內嵌類。

            3你測試過虛函數么?
            56 {
            57 T_HANDLER FuncHandler;
            58 void * pFPointer;
            59 };
            上面的語法對虛函數能用么?我記得虛函數指針是一個類似于__thunk{...}的結構,具體我也不清楚了。

            另外,我覺得類似的實現有兩個問題導致其不能成為通用方法:
            1對象生存期的問題,那個OwnClassHandler要是被析構了怎么辦?要是Event在OwnClassHandler之前被析構了怎么辦?我的辦法是設計兩個基本父類實現析構之前互相通知。但是這樣要求所有想把自己的成員函數“委托”給Event的類都要繼承自一個父類,但是這顯然是個“不情之請”。或許可以通過模板和宏來代替,最好像QT那樣,一句Q_OBJECT搞定。

            2關鍵在于eve->Bind(&class1,&MyClass::func)這句,在將對象的成員函數委托給事件的操作中,竟然要知道對象是什么類型,這顯然也是個“不情之請”。我覺得要解決這個問題必然涉及到類似于反射的機制,但那又是另一個冗繁的故事了。

            以上個人看法,有什么不確切的地方還請指正。
              回復  更多評論
              
            # re: 實現事件的封裝(類似C#的 delegate) 2009-07-26 14:05 CY
            1:由于我要實現的事件機制是可以綁定多個函數的。所以封裝后,有了統一的接口,就可以放進容器。如果不想綁定多個函數的話,你說得沒錯,可以直接一個類模板搞定

            2:內嵌沒有試過,應該沒有問題,只要代碼第21行、第53行的類型定義對外可見就行了

            3:虛函數剛剛測試過,可行!

            另外1:這個問題確實沒有注意到。覺得對于C++挺難,回去研究~~
            2:C++是靜態語言,沒有辦法,之前看過一高手在C++上實現反射,要把所有類型都預定義才行,現在還不太明白,但可以確定的是,反射的實現,也需要“不情之請”。  回復  更多評論
              
            # re: 實現事件的封裝(類似C#的 delegate)[未登錄] 2009-07-27 10:33 duzhongwei
            我上次做了個類似AS 3.0事件機制的

            IEventListener
              回復  更多評論
              
            国产福利电影一区二区三区久久老子无码午夜伦不 | 国产精品久久久久久久人人看 | 丁香五月综合久久激情| 久久香综合精品久久伊人| 热99RE久久精品这里都是精品免费 | 国产精品无码久久四虎| 18岁日韩内射颜射午夜久久成人 | 国产精品欧美亚洲韩国日本久久| 青青热久久综合网伊人| 2020最新久久久视精品爱 | 亚洲一区中文字幕久久| 久久精品国产一区二区电影| 999久久久免费精品国产| 狠狠精品久久久无码中文字幕 | 大美女久久久久久j久久| 久久精品国产一区二区| 久久久久久精品久久久久| 久久99久国产麻精品66| 99久久er这里只有精品18| 日韩精品久久久久久| 老司机午夜网站国内精品久久久久久久久 | 国产高潮国产高潮久久久91 | 狠狠精品久久久无码中文字幕| 久久午夜伦鲁片免费无码| 久久本道伊人久久| 久久不见久久见免费影院www日本| 无码精品久久一区二区三区| 久久久久久久97| 四虎国产精品免费久久久| 一本久久综合亚洲鲁鲁五月天| 日日躁夜夜躁狠狠久久AV| 99久久无码一区人妻| 中文字幕无码免费久久| 国产精品成人99久久久久| 久久综合亚洲色HEZYO社区| AV狠狠色丁香婷婷综合久久| 久久亚洲av无码精品浪潮| 久久99热只有频精品8| 精品久久久久久久国产潘金莲| 伊人热人久久中文字幕| 久久久久亚洲av无码专区|