【已解決】C++ Event 的實作方式
Event 在 Windows 的程式設計中,已經習以為常,尤其是 Windows 的 Event。但要在 C++ 中實作,還真不曉得要如何下手,原本在 C# 中如此基本的東西,轉到 C++ 竟是如此困難。
還好 Microsoft 還是留了一手 Event Handling,但看了半天還不是很懂,於是從 Sample code 中實驗終於大致瞭解了,所以記錄以備後用 (雖然 Microsoft 說這個功能要取消了,不過取消前還是將就著用吧!)
PS : Event Handler 使用完畢後必須執行 unhook 的動作,否則會產生 Memory Leaks
其實用觀察者模式就可以輕易地實作 Event 的功能了!!!
還好 Microsoft 還是留了一手 Event Handling,但看了半天還不是很懂,於是從 Sample code 中實驗終於大致瞭解了,所以記錄以備後用 (雖然 Microsoft 說這個功能要取消了,不過取消前還是將就著用吧!)
#include "stdafx.h" #include <iostream> using namespace std; [event_source(native)] struct IAnimal { virtual void Move() = 0; __event void OnMoved(int number); }; class Dog : public IAnimal { public: void Move() { cout << "Dog is moving." << endl; __raise OnMoved(5); } }; class Cat : public IAnimal { public: void Move() { cout << "Cat is moving." << endl; __raise OnMoved(7); } }; [event_receiver(native)] class Home { public: void OnMoved(int number) { cout << "It has moved " << number << " steps at home." << endl; } }; [event_receiver(native)] class Office { public: void OnMoved(int number) { cout << "It has moved " << number << " steps at office." << endl; } }; int _tmain(int argc, _TCHAR* argv[]) { Dog dog; Cat cat; Home home; Office office; __hook(&Dog::OnMoved, &dog, &Home::OnMoved, &home); __hook(&Cat::OnMoved, &cat, &Office::OnMoved, &office); dog.Move(); cat.Move(); __unhook(&Dog::OnMoved, &dog, &Home::OnMoved, &home); __unhook(&Cat::OnMoved, &cat, &Office::OnMoved, &office); return 0; }
- 觸發 Event 的 class 為發送端,必須在 class 宣告前面加上 [event_source(native)] 的屬性,並在 Event 函式簽章前面加上 __event。因目前在實作介面,所以就把 Event 宣告在上層的介面中,則實作該介面的 class 即繼承該 Event。
- class 中的 Method 要觸發 Event,只要在 Event 函式前面加上 __raise 呼叫即可。
- Event Handler 的 class 為接收端,必須在 class 宣告前面加上 [event_receiver(native)] 的屬性。
- 要連接 Event 與 Event Handler 必須使用 __hook,若在接收端 class 的 Method 中使用,則可以省略第 4 個參數 (預設值為 this)。而第 1 個參數也可以直接用介面 IAnimal::OnMoved,這樣方便實作該介面的 class 設定。
- 同一個 Event 可以串接多個 Event Handler,但最後 hook 的 Handler 會最先執行,如果有順序要求的話要特別注意。
- 若不使用該 EventHandler 則要呼叫 __unhook 移除,若該 Event 串接多個 Event Handler,則可以隨時移除其中任何一個,並沒有順序關係。
Dog is moving. It has moved 5 steps at home. Cat is moving. It has moved 7 steps at office.
PS : Event Handler 使用完畢後必須執行 unhook 的動作,否則會產生 Memory Leaks
其實用觀察者模式就可以輕易地實作 Event 的功能了!!!
留言