C++ 自定義事件機制2
阿新 • • 發佈:2019-02-13
可以使用成員函式指標,用到了類模版!
---------------------------------------------------------------
1、要定義一個事件基類,可以使用它傳遞不懂型別的引數。
myevent.h
#pragma once #include <iostream> #include <string> using namespace std; class MyEvent { public: MyEvent(string type); ~MyEvent(); string getType(); protected: private: string _type; };
myevent.cpp
#include "myevent.h"
MyEvent::MyEvent(string type)
{
_type = type;
cout << "MyEvent()" << endl;
}
MyEvent::~MyEvent()
{
cout << "~MyEvent()" << endl;
}
std::string MyEvent::getType()
{
return _type;
}
2、然後要有一個型別和函式指標的模版類。
eventitem.h
#pragma once #include "myevent.h" #include <memory> template <typename T> class EventItem { typedef void(T::*ItemFUN)(MyEvent&); public: EventItem() { cout << "EventItem()" << endl; } ~EventItem() { cout << "~EventItem()" << endl; } void (T::*f)(MyEvent&); shared_ptr<T> t; };
3、定義事件收發管理類
eventdispatcher.h
#pragma once #include <unordered_map> #include <string> #include "myevent.h" #include <iostream> #include "eventitem.h" #include <memory> using namespace std; template<typename T> class EventDispatcher { typedef void(T::*EventFun)(MyEvent&); public: static void addEventListener(string type, shared_ptr<T> t, EventFun f); static void dispatchEvent(shared_ptr<MyEvent> sp); static void removeEventListener(string type); static bool hasEventListener(string type); private: static unordered_map<string, shared_ptr<EventItem<T>>> events; }; template<typename T> unordered_map<string, shared_ptr<EventItem<T>>> EventDispatcher<T>::events; template<typename T> void EventDispatcher<T>::addEventListener(string type, shared_ptr<T> t, EventFun f) { if (!hasEventListener(type)) { shared_ptr<EventItem<T>> spItem = make_shared<EventItem<T>>(); spItem->t = t; spItem->f = f; events[type] = spItem; } else{ cout << "事件 " << type << " 已經定義" << endl; } } template<typename T> void EventDispatcher<T>::dispatchEvent(shared_ptr<MyEvent> sp) { string& temp = sp->getType(); if (hasEventListener(temp)) { shared_ptr<EventItem<T>> spItem = events[temp]; ((*spItem).t->*(*spItem).f)(*sp); cout << spItem->t->i << endl; } else{ cout << "事件 " << temp << " 未定義" << endl; } } template<typename T> void EventDispatcher<T>::removeEventListener(string type) { if (hasEventListener(type)) { events.erase(type); } else{ cout << "事件 " << type << " 未定義" << endl; } } template<typename T> bool EventDispatcher<T>::hasEventListener(string type) { if (events[type] != nullptr) { return true; } return false; }
至此就可以使用了簡單吧~
===========================================================================================
使用案例:
main.cpp
#include <iostream>
#include "eventdispatcher.h"
#include <memory>
class Test
{
public:
int i;
Test()
{
cout << "Test()" << endl;
}
~Test()
{
cout << "~Test()" << endl;
}
void test(MyEvent& e)
{
cout << "what the hell!!!" << endl;
i++;
}
protected:
private:
};
void fun()
{
shared_ptr<Test> pt = make_shared<Test>();
pt->i = 10;
EventDispatcher<Test>::addEventListener("hello", pt, &Test::test);
EventDispatcher<Test>::addEventListener("jj", pt, &Test::test);
}
void del()
{
EventDispatcher<Test>::removeEventListener("hello");
}
int main()
{
fun();
del();
system("pause");
return 0;
}