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

隨筆 - 55  文章 - 15  trackbacks - 0
<2012年4月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

常用鏈接

留言簿

隨筆分類

隨筆檔案

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

本文章為farproc.com站長袁曉輝(海洋)的原創(chuàng)文章,作者保留所有權(quán)利。如果轉(zhuǎn)載,請務(wù)必注明來自www.farproc.com!!

 

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

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

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

一、C#

我們先來看一個C#中一個“事件”的最簡單例子:

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

using System;

 

namespace eventtest

{

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

    public delegate void EventHandler();

 

    /// <summary>

    ///

    /// </summary>

    public class MyClass

    {

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

        public MyClass(){}

        //聲明一個事件

        public event EventHandler AEvent;

        //激發(fā)事件

        public void FireEvent()

        {

            if(AEvent != null)

            {

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

                AEvent();

            }

        }

    }

}

 

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

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

using System;

 

namespace eventtest

{

    /// <summary>

    /// Class1 的摘要說明。

    /// </summary>

    class Class1

    {

        /// <summary>

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

        /// </summary>

        [STAThread]

        static void Main(string[] args)

        {

            MyClass Obj = new MyClass();

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

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

 

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

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

           

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

            Console.ReadLine();

        }

       

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

        public static  void MyEventHandler()

        {

            Console.WriteLine("This is a event!");

        }

    }

   

}

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

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

 

二、C++版

下面我們在C++中模擬該機(jī)制:

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

在VC6中新建一個win32 console app,命名為“cppevent“。新建一個.h頭文件,命名為“event.h”,代碼如下:

//event.h

 

template <typename Handler>

class event

{

private:

         Handler m_Handler;

protected:

         //模擬C# event add/remove訪問器

         //如果要重新實(shí)現(xiàn)add/remove請在派生類中重寫這兩個函數(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){}

         //+= 操作符

         eventoperator += (const Handler value)

         {

                   add(value);

                   return *this;

         }

         //-=操作符

         eventoperator -= (const Handler value)

         {

                   remove(value);

                   return *this;

         }

         //PFN_EVENT_HANDLE 操作符

         operator Handler()

         {

                   return m_Handler;

         }

};

 

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

C++版的MyClass如下:

//MyClass.h

#include "event.h"

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

typedef void(*EventHandler)();

 

class MyClass

{

public:

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

         MyClass(){};

         //聲明一個事件

         event<EventHandlerAEvent;

         //激發(fā)事件

         void FireEvent()

         {

                   if(AEvent != NULL)

                   {

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

                            ((EventHandler)AEvent)();

                   };

         }

 

};

 

C#版的MyClass比較一下你就會發(fā)現(xiàn)代碼非常接近,當(dāng)然,C#是在語言級直接支持event關(guān)鍵字的,而C++不支持,用模板類代替,所以聲明事件的代碼有些不一樣。還有就是FireEvent()C++不能把event對象直接當(dāng)做函數(shù)來調(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 argccharargv[])

{

         MyClass Obj;

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

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

 

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

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

 

 

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

         char n;

         scanf("%c", &n);

         return 0;

}

 

void MyEventHandler()

{

         printf("This is a event!/n");

}

 

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

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

 

三、總結(jié)

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

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

<>

posted on 2012-04-26 17:52 Dino-Tech 閱讀(635) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            一本一道久久综合狠狠老精东影业 | 亚洲理伦电影| 久久久综合网| 久久精品亚洲一区| 欧美在线在线| 久久露脸国产精品| 欧美二区乱c少妇| 亚洲精品午夜| 亚洲一区中文| 麻豆精品91| 欧美三级电影大全| 国产欧美精品在线| 伊人夜夜躁av伊人久久| 亚洲激情第一区| 亚洲影院高清在线| 久久米奇亚洲| 亚洲精品免费在线观看| 玖玖视频精品| 一本色道久久综合亚洲精品按摩| 亚洲欧美另类中文字幕| 蜜桃精品久久久久久久免费影院| 欧美日本在线视频| 国产手机视频精品| 亚洲免费av电影| 久久久xxx| 99国产精品| 久久蜜桃精品| 国产精品久久久久久久久免费桃花| 狠狠色噜噜狠狠狠狠色吗综合| 一本大道久久a久久精品综合 | 伊人久久大香线蕉综合热线| 9人人澡人人爽人人精品| 欧美在线免费视频| 亚洲精品乱码久久久久久蜜桃91| 欧美中文字幕不卡| 国产精品成人aaaaa网站| 在线看一区二区| 欧美在线国产| 99re6热只有精品免费观看 | 久久综合色88| 国产一区91精品张津瑜| 亚洲小说欧美另类社区| 欧美高清在线| 久久久精品网| 国产一区在线免费观看| 午夜日韩在线| 亚洲线精品一区二区三区八戒| 美女在线一区二区| 狠狠爱www人成狠狠爱综合网| 亚洲自拍三区| 一本色道**综合亚洲精品蜜桃冫 | 欧美18av| 另类专区欧美制服同性| 一本色道久久综合精品竹菊| 欧美精品一区二区三| 在线观看视频欧美| 久久亚洲欧美| 久久久久国色av免费看影院 | 久久精品国产一区二区三| 国产精品乱码一区二区三区| 一个色综合导航| 亚洲精品国产精品国自产在线| 另类激情亚洲| 亚洲精品国产精品国自产观看浪潮 | 国产精品美女一区二区| 亚洲午夜精品久久久久久浪潮 | 亚洲一区二区三区四区五区黄| 亚洲精品乱码久久久久久蜜桃91 | 99精品国产福利在线观看免费| 欧美精品一区二区精品网| 亚洲精品免费在线观看| 91久久精品国产| 欧美日韩欧美一区二区| 亚洲午夜视频| 香蕉久久夜色精品国产使用方法| 国产一区二区三区av电影| 嫩草国产精品入口| 欧美精品在欧美一区二区少妇| 99国产精品久久久久老师| 一区二区三区视频观看| 国产午夜精品久久久| 欧美风情在线观看| 欧美日韩国产综合一区二区| 亚洲欧美日韩在线一区| 久久国产精品久久w女人spa| 亚洲级视频在线观看免费1级| 99精品久久久| 精品福利免费观看| 亚洲美女黄网| 激情婷婷亚洲| 夜夜嗨av色综合久久久综合网| 国产亚洲激情| 亚洲国产欧美一区二区三区久久 | 毛片av中文字幕一区二区| 一区二区不卡在线视频 午夜欧美不卡在| 亚洲最新视频在线| 在线精品观看| 亚洲午夜黄色| 亚洲国产精品毛片| 亚洲一区二区三区乱码aⅴ蜜桃女| 国内成人自拍视频| 亚洲欧美经典视频| 欧美在线免费观看| 一区二区三区四区五区精品视频 | 亚洲精品免费一二三区| 国产一区视频在线看| 夜夜夜久久久| 亚洲人成网站777色婷婷| 一区二区三区四区五区精品视频| 国产婷婷色一区二区三区四区| 最新成人av网站| 伊人影院久久| 午夜国产一区| 亚洲女人av| 欧美日韩国产高清| 亚洲电影观看| 精品成人一区二区| 午夜精品区一区二区三| 亚洲视频欧洲视频| 欧美成人中文字幕在线| 久久青青草原一区二区| 国产精品毛片a∨一区二区三区|国 | 欧美不卡视频一区发布| 国产欧美一区二区三区在线看蜜臀 | 欧美日韩一区不卡| 欧美激情一区二区在线 | 在线视频亚洲一区| 日韩视频第一页| 美女精品在线观看| 老司机精品视频网站| 国产亚洲日本欧美韩国| 亚洲午夜女主播在线直播| 一本一本久久a久久精品综合麻豆 一本一本久久a久久精品牛牛影视 | 欧美一二区视频| 国产精品99免费看| 亚洲精品久久久久中文字幕欢迎你| 一区二区在线免费观看| 久久精品视频在线播放| 欧美中文字幕久久| 国产欧美日韩综合| 午夜日韩电影| 久久久久成人网| 在线观看日韩www视频免费 | 蜜臀久久99精品久久久久久9| 老司机一区二区| 在线观看不卡| 美女脱光内衣内裤视频久久影院| 亚洲大片在线观看| 麻豆精品一区二区av白丝在线| 欧美老女人xx| 一本色道久久综合亚洲精品不卡 | 欧美一二三区精品| 国产午夜精品久久| 久久精品夜夜夜夜久久| 麻豆精品在线视频| 亚洲人人精品| 欧美性大战久久久久| 亚洲自拍偷拍视频| 老色鬼精品视频在线观看播放| 亚洲精品乱码久久久久久黑人| 欧美精品偷拍| 亚洲欧美日韩电影| 免费毛片一区二区三区久久久| 最新国产成人在线观看| 欧美日韩一区在线播放| 西西人体一区二区| 欧美激情在线狂野欧美精品| 亚洲性图久久| 黄色一区二区三区| 欧美日韩和欧美的一区二区| 亚洲一区二区免费| 欧美成人精品影院| 亚洲一区二区三区影院| 国产一区二区欧美| 欧美精品一区在线播放| 欧美一区二区啪啪| 亚洲精品色婷婷福利天堂| 香蕉乱码成人久久天堂爱免费 | 久久一区亚洲| 亚洲在线播放电影| 亚洲国产精品高清久久久| 亚洲在线成人| 亚洲精品欧美在线| 国产欧美精品在线播放| 欧美激情精品| 久久久久九九九九| 亚洲深夜福利在线| 亚洲国产一区二区三区高清 | 亚洲视频精选在线| 欧美成人在线免费观看| 羞羞漫画18久久大片| 亚洲精品一二区| 含羞草久久爱69一区| 国产精品户外野外| 欧美国产日韩在线| 久久久久国产精品厨房| 午夜精品久久久久影视 | 亚洲男人天堂2024| 日韩午夜精品视频| **欧美日韩vr在线|