C++模擬event關(guān)鍵字具體實現(xiàn)方案
在C++編程語言中,其實也是有它不能夠支持的功能,但是可以通過各種方法來進(jìn)行模擬以達(dá)到編程人員程序開發(fā)的需求。在這里我們就會為大家詳細(xì)介紹有關(guān)C++模擬event關(guān)鍵字的相關(guān)操作方法。
在VC6中新建一個win32 console app,命名為“cppevent“。新建一個.h頭文件,命名為“event.h”,代碼如下:
- //event.h
 - template <typename Handler>
 - class event
 - {
 - private:
 - Handler m_Handler;
 - protected:
 - //模擬C# event 的add/remove訪問器
 - //如果要重新實現(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){}
 - //+= 操作符
 - 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;
 - }
 - };
 
為了能夠在在C++模擬event關(guān)鍵字中定義是指定事件處理函數(shù)的原型,我使用了template,為了能和C#一樣用+=和-=來定制和撤消事件,我重載了這兩個操作符(C#不支持操作符重載),為了能像C#一樣直接把event當(dāng)做函數(shù)調(diào)用,我有重載了Handler自定義轉(zhuǎ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<EventHandler> AEvent;
 - //激發(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 argc, char* argv[])
 - {
 - 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#一樣用“+=”和“-=”來定制事件和撤消事件定制,并在Obj的FireEvent()被調(diào)用時收到事件通知,輸出文本。#t#
鑒于篇幅的原因,我們沒有仔細(xì)比較兩個版本的event的add和remove訪問器/成員函數(shù),其實二者也是非常類似的,你可以自己試試。C++版的event的add和remove均為virtual的,你可以從event類繼承出來一個MyEvent類,然后重新實現(xiàn)這兩個函數(shù),就可以定制自己的add和remove了。這和C#的add/remove訪問器的也是非常相像的。
總結(jié)
通過C++模擬event關(guān)鍵字的實現(xiàn),我們可以從更深的層次理解C#的event機(jī)制,更重要的是我們用自己所熟悉的東西(C++,模板類)來模仿并解釋了我們目前還不太熟悉的東西(C#,event)。
其實,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ù)邏輯的處理上。















 
 
 







 
 
 
 