青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

用C++模擬C#的event機(jī)制

作為一個(gè)C++程序員,學(xué)習(xí)C#應(yīng)該不是一件很困難的事情,因?yàn)?/span>C#的許多特性都是從C++“繼承”(不精確的說(shuō)法)來(lái)的。但是C#作為一門全新的編程語(yǔ)言,它必然有自己的新特性,而這些C++中并不存在的新特性正是我們從C++轉(zhuǎn)向C#的過(guò)程中必須認(rèn)真重新學(xué)習(xí)的東西。“事件(event)”是C#的一個(gè)比較簡(jiǎn)單的新特性,我們今天就從“事件”開始,看一看C#的事件到底是怎么回事。

C#的事件和Windows窗口編程中提到的“事件”、“消息”、“事件驅(qū)動(dòng)”等在概念上是很類似的。我們?cè)谝粋€(gè)窗口上移動(dòng)鼠標(biāo)指針,系統(tǒng)就會(huì)產(chǎn)生WM_MOUSEMOVE消息(在vb中就是激發(fā)mousemove事件),只要我們告訴系統(tǒng)一個(gè)函數(shù)指針,系統(tǒng)就會(huì)通過(guò)這個(gè)回調(diào)函數(shù)通知我們,這是Windows窗口編程中的“事件”。C#中的事件的外延更廣,任何一個(gè)對(duì)象都可以擁有事件,客戶可以“定制”該對(duì)象的事件,當(dāng)該對(duì)象的內(nèi)部狀態(tài)發(fā)生特定的改變時(shí),就會(huì)通過(guò)定制事件時(shí)指定的函數(shù)代理(delegate)調(diào)用這個(gè)函數(shù)通知客戶。當(dāng)客戶不在需要事件通知時(shí),可以“撤消”對(duì)該事件的定制。

Now is the show time!模仿秀現(xiàn)在開始!

一、C#

我們先來(lái)看一個(gè)C#中一個(gè)“事件”的最簡(jiǎn)單例子:

VS.NET中新建一個(gè)C#ConsoleApplication,項(xiàng)目名稱為“eventtest”。為該項(xiàng)目新加一個(gè)類MyClass,對(duì)應(yīng)的源文件為MyClass.cs代碼如下:

using System;

namespace eventtest

{

    //定義EventHandler函數(shù)代理

    public delegate void EventHandler();

    /// <summary>

    ///

    /// </summary>

    public class MyClass

    {

        //構(gòu)造函數(shù)

        public MyClass(){}

        //聲明一個(gè)事件

        public eventEventHandler AEvent;

        //激發(fā)事件

        public voidFireEvent()

        {

            if(AEvent != null)

            {

                //直接把event當(dāng)做函數(shù)調(diào)用

                AEvent();

            }

        }

    }

}

 

public event EventHandlerAEvent;就是給MyClass定義了一個(gè)事件(通過(guò)event關(guān)鍵字),其事件處理函數(shù)(通知函數(shù))的原型由EventHandler函數(shù)代理(類似C++中的函數(shù)指針)指定。

FireEvent()成員函數(shù)用于激發(fā)該事件,如果客戶定制了該event,當(dāng)本類對(duì)象的FireEvent()公開方法被調(diào)用時(shí),客戶應(yīng)該可以得到通知。在Main函數(shù)里寫如下代碼:

using System;

namespace eventtest

{

    /// <summary>

    /// Class1 的摘要說(shuō)明。

    /// </summary>

    class Class1

    {

        /// <summary>

        /// 應(yīng)用程序的主入口點(diǎn)。

        /// </summary>

        [STAThread]

        static void Main(string[] args)

        {

            MyClassObj = new MyClass();

            Obj.AEvent+= new EventHandler(MyEventHandler);//定制事件

            Obj.FireEvent();//這行將導(dǎo)致MyEventHandler被調(diào)用

            Obj.AEvent-= new EventHandler(MyEventHandler);//撤消事件

            Obj.FireEvent();//這里將不會(huì)引發(fā)事件

           

            Console.WriteLine("結(jié)束!");

            Console.ReadLine();

        }

       

        //事件處理函數(shù)

        public static voidMyEventHandler()

        {

            Console.WriteLine("Thisis a event!");

        }

    }

   

}

首先寫一個(gè)具有適當(dāng)形式的事件處理(通知)函數(shù)MyEventHandler,然后通過(guò)Obj.AEvent+= new EventHandler(MyEventHandler)來(lái)定制事件。通過(guò)“-=”來(lái)撤消事件定制。

運(yùn)行程序我們可以發(fā)現(xiàn),當(dāng)客戶(Class1)定制了ObjAEvent事件后,在ObjFireEvent()成員函數(shù)被調(diào)用時(shí),客戶可以在MyEventHandler函數(shù)中得到通知(在這里只是簡(jiǎn)單地輸出一個(gè)文本)。而當(dāng)客戶撤消該事件的定制后,就不會(huì)再得到該事件通知。

 

二、C++

下面我們?cè)?span>C++中模擬該機(jī)制:

由于C++不支持event關(guān)鍵字,我們就必須自己寫代碼。在這里我通過(guò)模板類的手段來(lái)實(shí)現(xiàn),因?yàn)樵撌侄螌?shí)現(xiàn)的效果和C#比較類似。

VC6中新建一個(gè)win32console app,命名為“cppevent“。新建一個(gè).h頭文件,命名為“event.h”,代碼如下:

//event.h

template <typename Handler>

class event

{

private:

         Handler m_Handler;

protected:

         //模擬C# event add/remove訪問(wèn)器

         //如果要重新實(shí)現(xiàn)add/remove請(qǐng)?jiān)谂缮愔兄貙戇@兩個(gè)函數(shù)

         virtual void add(const Handler value){m_Handler = value;};

         virtual void remove(const Handler value){if(value == m_Handler)m_Handler = NULL;};

public:

         //構(gòu)造函數(shù)

         event():m_Handler(NULL){}

         //+= 操作符

         event& operator += (const Handler value)

         {

                   add(value);

                   return *this;

         }

         //-=操作符

         event& operator -= (const Handler value)

         {

                   remove(value);

                   return *this;

         }

         //PFN_EVENT_HANDLE 操作符

         operator Handler()

         {

                   return m_Handler;

         }

};

 

為了能夠在定義是指定事件處理函數(shù)的原型,我使用了template,為了能和C#一樣用+=-=來(lái)定制和撤消事件,我重載了這兩個(gè)操作符(C#不支持操作符重載),為了能像C#一樣直接把event當(dāng)做函數(shù)調(diào)用,我有重載了Handler自定義轉(zhuǎn)換操作符,可惜的是,這一點(diǎn)模擬得不是很像,在調(diào)用時(shí)還必須來(lái)一次強(qiáng)制轉(zhuǎn)換才可以:(,具體參看后面的代碼:

C++版的MyClass如下:

//MyClass.h

#include "event.h"

//定義EventHandler的函數(shù)指針類型

typedef void(*EventHandler)();

class MyClass

{

public:

         //構(gòu)造函數(shù)

         MyClass(){};

         //聲明一個(gè)事件

         event<EventHandler> AEvent;

         //激發(fā)事件

         void FireEvent()

         {

                   if(AEvent != NULL)

                   {

                            //C++中必須用EventHandler進(jìn)行強(qiáng)制類型轉(zhuǎn)換

                            ((EventHandler)AEvent)();

                   };

         }

};

 

C#版的MyClass比較一下你就會(huì)發(fā)現(xiàn)代碼非常接近,當(dāng)然,C#是在語(yǔ)言級(jí)直接支持event關(guān)鍵字的,而C++不支持,用模板類代替,所以聲明事件的代碼有些不一樣。還有就是FireEvent()C++不能把event對(duì)象直接當(dāng)做函數(shù)來(lái)調(diào)用,多了強(qiáng)制類型轉(zhuǎn)換。

 

C++版的客戶代碼如下:

//cppevent.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include "MyClass.h"

//向前聲明

void MyEventHandler();

int main(int argc, char* argv[])

{

         MyClass Obj;

         Obj.AEvent += MyEventHandler;//定制事件

         Obj.FireEvent();//這行將導(dǎo)致MyEventHandler被調(diào)用

         Obj.AEvent -= MyEventHandler;//撤消事件

         Obj.FireEvent();//這個(gè)將不會(huì)引發(fā)事件

         printf("結(jié)束!\n");

         char n;

         scanf("%c",&n);

         return 0;

}

void MyEventHandler()

{

         printf("Thisis a event!\n");

}

 

我們可以看到,可C#版的客戶代碼相比,核心部分是非常接近的,我們已經(jīng)可以和C#一樣用“+=”和“-=”來(lái)定制事件和撤消事件定制,并在ObjFireEvent()被調(diào)用時(shí)收到事件通知,輸出文本。

鑒于篇幅的原因,我們沒(méi)有仔細(xì)比較兩個(gè)版本的eventaddremove訪問(wèn)器/成員函數(shù),其實(shí)二者也是非常類似的,你可以自己試試。C++版的eventaddremove均為virtual的,你可以從event類繼承出來(lái)一個(gè)MyEvent類,然后重新實(shí)現(xiàn)這兩個(gè)函數(shù),就可以定制自己的addremove了。這和C#add/remove訪問(wèn)器的也是非常相像的。

 

三、總結(jié)

通過(guò)這場(chǎng)“模仿show”我們可以從更深的層次理解C#event機(jī)制,更重要的是我們用自己所熟悉的東西(C++,模板類)來(lái)模仿并解釋了我們目前還不太熟悉的東西(C#event)。

其實(shí),C#delegate就是C++的函數(shù)指針,C# event的核心機(jī)制就是C++中的模板(定義event時(shí)表現(xiàn)出來(lái))和運(yùn)算符重載(+=-=和直接把event當(dāng)做函數(shù)調(diào)用)的結(jié)合體。C#C++中容易出錯(cuò)的部分用“新特性”封裝了起來(lái),把這部分工作從programmer身上轉(zhuǎn)移到了compiler身上,讓我們把更多的精力集中到業(yè)務(wù)邏輯的處理上。

posted on 2008-06-30 06:02 RedLight 閱讀(686) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C++功夫篇

<2008年4月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

導(dǎo)航

統(tǒng)計(jì)

公告


Name: Galen
QQ: 88104725

常用鏈接

留言簿(3)

隨筆分類

隨筆檔案

相冊(cè)

My Friend

搜索

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲欧美国产va在线影院| 国内精品99| 久久精品视频在线播放| 亚洲欧美日韩专区| 午夜在线精品偷拍| 欧美一区二区视频97| 欧美伊久线香蕉线新在线| 久久精品一二三区| 悠悠资源网久久精品| 亚洲人妖在线| 欧美一区二区国产| 欧美刺激性大交免费视频| 亚洲剧情一区二区| 欧美在线观看视频在线| 美女性感视频久久久| 欧美日韩精品免费观看视一区二区 | 亚洲午夜av在线| 在线亚洲高清视频| 香蕉免费一区二区三区在线观看| 午夜精品视频| 快播亚洲色图| 国产精品视频免费观看| 亚洲国产精品一区二区www在线| 夜夜嗨av色一区二区不卡| 欧美在线免费观看视频| 美脚丝袜一区二区三区在线观看| 亚洲国产精品高清久久久| 亚洲精品欧美日韩| 欧美一区二区精品| 欧美日韩妖精视频| 亚洲国产天堂久久国产91| 欧美一区二视频在线免费观看| 亚洲第一综合天堂另类专| 性欧美1819性猛交| 国产精品成人免费| 日韩一级免费| 欧美国产亚洲视频| 欧美在线亚洲在线| 国产精品久久久久久久app| 91久久精品美女高潮| 久久久久久亚洲精品不卡4k岛国| 日韩视频一区二区三区| 久久视频精品在线| 国产亚洲精品bv在线观看| 亚洲欧美在线磁力| 99热这里只有成人精品国产| 久久综合狠狠综合久久综合88| 国产欧美 在线欧美| 亚洲尤物视频网| 亚洲另类在线视频| 欧美日韩国产a| 亚洲精品婷婷| 亚洲国产精品小视频| 久久久爽爽爽美女图片| 国产在线拍偷自揄拍精品| 久久精品30| 久久成人免费| 狠狠色狠狠色综合日日tαg| 久久国产精品第一页| 欧美中文字幕第一页| 国产亚洲欧美一区二区三区| 久久久久久夜| 久久伊人一区二区| 91久久中文| 亚洲激情影院| 欧美日韩你懂的| 亚洲欧美偷拍卡通变态| 亚洲福利av| 狠狠久久五月精品中文字幕| 久久成人在线| 久久久噜噜噜久噜久久| 亚洲成色www久久网站| 欧美成人免费全部| 欧美激情乱人伦| 亚洲天堂免费观看| 亚洲一区高清| 国产亚洲一区二区精品| 美日韩精品视频| 牛牛影视久久网| 一区二区日韩| 亚洲欧美精品在线观看| 精品999在线播放| 亚洲国产美女精品久久久久∴| 欧美精品福利在线| 亚洲欧美卡通另类91av| 欧美一区二区三区免费大片| 激情小说另类小说亚洲欧美| 欧美成人影音| 国产精品高潮呻吟久久| 久久国产乱子精品免费女| 欧美fxxxxxx另类| 亚洲一区在线看| 久久免费少妇高潮久久精品99| 亚洲精品一区二区三区福利| 亚洲一区二区三| 亚洲国产成人不卡| 亚洲一区免费网站| 亚洲高清三级视频| 在线视频欧美日韩| 最新国产の精品合集bt伙计| 亚洲专区在线视频| 亚洲看片网站| 久久国产精品久久久久久久久久 | 亚洲精品综合在线| 亚洲欧美在线观看| 亚洲国产一区二区三区青草影视 | 亚洲伊人第一页| 亚洲精品国产欧美| 欧美一区国产一区| 一区二区三区视频观看| 欧美中文在线视频| 亚洲欧美日韩国产综合| 欧美大片免费观看| 蜜桃伊人久久| 国产日韩综合| 这里只有精品视频| 亚洲精品欧美一区二区三区| 久久精品国产亚洲高清剧情介绍| 一区二区三区日韩精品视频| 麻豆freexxxx性91精品| 久久免费高清| 国内外成人免费激情在线视频网站 | 亚洲一区不卡| 欧美精品一区二区三区蜜臀| 快she精品国产999| 国产又爽又黄的激情精品视频 | 久久福利一区| 欧美视频免费看| 91久久午夜| 亚洲激情社区| 六月婷婷一区| 女人天堂亚洲aⅴ在线观看| 国产精品免费视频xxxx| 在线综合欧美| 午夜精品福利在线| 国产精品综合| 久久精品官网| 欧美成人资源| 妖精成人www高清在线观看| 欧美电影在线播放| 亚洲三级影片| 亚洲特级片在线| 国产精品麻豆成人av电影艾秋 | 午夜精品福利电影| 久久五月天婷婷| 亚洲国产高清视频| 欧美精品在线看| 亚洲视频播放| 久久久久在线观看| 亚洲电影第三页| 欧美激情精品久久久六区热门| 亚洲国产精品久久久久婷婷884 | 欧美视频在线观看一区| 一区二区三区黄色| 香蕉久久夜色精品国产| 国产一区二区三区久久悠悠色av| 久久久久久九九九九| 亚洲国产裸拍裸体视频在线观看乱了中文 | 亚洲高清二区| 欧美精品一卡二卡| 亚洲一区影院| 免费欧美日韩| 一本一本久久a久久精品牛牛影视| 欧美理论电影在线播放| 亚洲欧美日韩国产成人精品影院| 久久九九国产精品| 亚洲欧洲一区二区三区| 欧美日韩日韩| 久久国产高清| 亚洲看片一区| 美女日韩欧美| 在线亚洲国产精品网站| 国产在线视频欧美| 欧美色综合网| 久久久久亚洲综合| 9久re热视频在线精品| 久久久在线视频| 亚洲视频大全| 亚洲大胆视频| 国产精品日日摸夜夜添夜夜av| 久久免费视频一区| 亚洲婷婷综合色高清在线| 欧美日韩美女在线| 久久亚洲一区二区| 亚洲国产视频一区| 欧美一区二区三区在线看| 亚洲国产精品久久久久秋霞蜜臀| 欧美噜噜久久久xxx| 久久久噜噜噜久久人人看| 亚洲图片欧美午夜| 91久久久久久久久久久久久| 久久亚洲私人国产精品va媚药| 亚洲在线一区二区三区| 亚洲美女少妇无套啪啪呻吟| 黄色成人av| 国产午夜精品福利| 欧美视频二区36p| 欧美精品情趣视频| 免费成人高清视频| 久久精精品视频|