C++ 自定义事件机制2
2015-06-16 08:59
465 查看
可以使用成员函数指针,用到了类模版!
---------------------------------------------------------------
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;
}
---------------------------------------------------------------
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;
}
相关文章推荐
- Effective C++ 条款50
- c++ new 的几个用法
- C++ Dog类
- 插入排序的C++实现
- 用C++进行函数式编程
- 开始学习C++心得实例(3)
- 【整理】--C++三种参数传递方式
- C++对象模型之默认构造函数的构造操作,拷贝构造函数同
- C++温习-标准库-vector
- 《C++语言基础》程序阅读——二进制文件及文件的随机读写(4)
- C++经典开源库
- C++ Tree类
- 15周《C++语言基础》程序阅读——二进制文件及文件的随机读写(2)(3)
- 浅谈C++多态性
- C语言之ASSERT
- C++温习-标准库-set
- 【C语言】指针是一个变量
- C++中const与指针、引用的分析
- hdu 1033 (bit masking, utilization of switch, '\0' as end of c string)
- C和C++程序员面试秘籍