• <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年6月>
            31123456
            78910111213
            14151617181920
            21222324252627
            2829301234
            567891011

            常用鏈接

            留言簿(8)

            隨筆分類

            隨筆檔案

            好友連接

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

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

            上大學(xué)開始接觸編程,一開始便學(xué)習(xí)C++,但是教科書對(duì)模板的介紹都比較少,當(dāng)時(shí)連比較基礎(chǔ)的C++都學(xué)得一塌糊涂,更不用說模板了。
            現(xiàn)在工作任務(wù)完成,有點(diǎn)空閑時(shí)間看《C++templates》,看到現(xiàn)在終于能寫點(diǎn)像樣的C++模板了。

            目前事件類的封裝還沒有對(duì)0--5個(gè)參數(shù)模板的特化,這里只貼出具有6個(gè)參數(shù)的事件類代碼:
              1#pragma once
              2#include <list>
              3using namespace std;
              4
              5//函數(shù)調(diào)用類抽象接口
              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//全局函數(shù)調(diào)用類
             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//成員函數(shù)調(diào)用類
             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())//已經(jīng)存在了,就不需要添加
            126            delete addone;//刪除臨時(shí)的new對(duì)象
            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())//存在,刪除節(jié)點(diǎn)和指針
            135        {
            136            delete (*delnode);
            137            FunctionList.erase(delnode);
            138        }

            139        delete delone;//刪除臨時(shí)的new對(duì)象
            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())//已經(jīng)存在
            146            delete addone;//刪除臨時(shí)的new對(duì)象
            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())//存在,刪除節(jié)點(diǎn)和指針
            156        {
            157            delete (*delnode);
            158            FunctionList.erase(delnode);
            159        }

            160        delete delone;//刪除臨時(shí)的new對(duì)象
            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}
            ;

            測(cè)試代碼:
             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}
            運(yùn)行結(jié)果:

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

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

            2個(gè)人覺得CY_FunctionInterface及其子類應(yīng)該是除了CY_Event之外都不應(yīng)該看到的,應(yīng)該設(shè)計(jì)成內(nèi)嵌類。

            3你測(cè)試過虛函數(shù)么?
            56 {
            57 T_HANDLER FuncHandler;
            58 void * pFPointer;
            59 };
            上面的語(yǔ)法對(duì)虛函數(shù)能用么?我記得虛函數(shù)指針是一個(gè)類似于__thunk{...}的結(jié)構(gòu),具體我也不清楚了。

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

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

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

            2:內(nèi)嵌沒有試過,應(yīng)該沒有問題,只要代碼第21行、第53行的類型定義對(duì)外可見就行了

            3:虛函數(shù)剛剛測(cè)試過,可行!

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

            IEventListener
              回復(fù)  更多評(píng)論
              
            亚洲欧美精品一区久久中文字幕| 久久青青草视频| 一级做a爰片久久毛片看看| 亚洲精品白浆高清久久久久久| 日本精品一区二区久久久| 久久精品亚洲男人的天堂| 久久久久成人精品无码中文字幕 | 久久久久久国产精品免费无码| 久久成人国产精品一区二区| 日韩人妻无码精品久久久不卡| 狠狠精品久久久无码中文字幕| 久久精品天天中文字幕人妻| 中文字幕精品久久久久人妻| 国产成人综合久久久久久| 国内精品久久久久久99蜜桃 | 亚洲国产精品人久久| 日韩精品久久久久久免费| 99久久国产亚洲综合精品| 久久精品成人欧美大片| 亚洲乱亚洲乱淫久久| 精品国产福利久久久| av无码久久久久不卡免费网站| 久久久久久伊人高潮影院| 国产精品成人久久久| 中文字幕无码久久人妻| 亚洲精品tv久久久久| 久久久久亚洲AV综合波多野结衣 | 久久无码精品一区二区三区| 国产2021久久精品| 18岁日韩内射颜射午夜久久成人| 久久国产亚洲精品麻豆| 久久久久久综合一区中文字幕| 国产精品久久精品| 婷婷综合久久狠狠色99h| 日本福利片国产午夜久久| 久久亚洲精品视频| 亚洲国产精品久久久久网站| 国产精品九九久久免费视频 | 亚洲中文久久精品无码| 亚洲精品国产美女久久久| 欧美一区二区三区久久综|