事件基本概念
操作系统或应用程序内部发生某件事,程序的某个组件需要响应该事件,并进行特定处理
面向对象架构中,事件响应函数最可能为成员函数
- 问题:指向类的成员函数的指针不可能转换为哑型指针
void*
,也不能随意转换为指向另一个类的成员函数的指针 - 解决方案:使用指向指向类成员函数的指针的指针,即二级指针
实现策略:事件委托模型
- Event类模板:管理事件响应者对象,实现事件多播
- EventResponsor类模板:响应者对象与响应者行为配对
- Empty类:委托模型和指针转换
认识不是很深,简单说说:
-
指向一个类的指针在某些情况下可以强制转换指向另一个类
-
指向一个类的成员函数的函数指针可以转换为指向另一个类的类型匹配的同型成员函数
-
成员函数指针的调用方法:
// obj时类对象;ip是指向类的成员函数的函数指针 (obj.*ip)(); *下面是几种错误的写法,要注意! * obj.*ip(); * obj.(*ip)(); * (obj.(*ip))(); */
-
不知道这个东西怎么用,仅仅能看懂代码
通过分析,我发现事件机制的核心是把响应者及其响应行为打包装到容器中,然后对事件的发生逐一作出响应。
事件机制版本一,使用指向指向类成员函数的指针的指针,即二级指针:
// 以下是Event.hpp的内容
#pragma once
#include <iostream>
#include <vector>
using namespace std;
// 空类,用于指代响应者对象
class Empty {};
// 事件响应者模板,保存特定事件的响应者与响应行为
template<typename EventAction>
class EventResponsor{
public:
EventResponsor(): actor(NULL), action(NULL) {}
EventResponsor(Empty* actor, EventAction *action):actor(actor), action(action) {}
friend bool operator == (const EventResponsor& lhs, const EventResponsor& rhs)
{return lhs.actor == rhs.actor && *(lhs.action) == *(rhs.action);}
public: // 公开数据成员,以方便使用者
Empty* actor;
EventAction* action; // 注意:EventAction本身就是一个指向类的成员函数的指针
};
// 事件类模板,用于管理特定事件的所有响应者
template< typename EventAction >
class Event{
public:
// 类型定义
typedef vector<EventResponsor<EventAction> > EventResponsors;
typedef typename vector<EventResponsor<EventAction> >::iterator EventIterator;
private:
EventResponsors _ers;
public:
virtual ~Event(){
for(EventIterator it = this->_ers.begin(); it != this->_ers.end(); ++it){
delete it->action;
it->action = nullptr;
}
}
EventResponsors & GetResponsors() { return this->_ers; }
// 事件绑定,将实际响应者和响应行为挂接到事件响应者对象上
template< typename Responsor, typename Action > // 模板类里面套模板函数
void Bind( Responsor* actor, Action action ){
Action* act = new Action( action );
EventResponsor< EventAction > er((Empty*)actor, (EventAction*)act); // 创建了事件响应对象
bool unbound = true;
for( EventIterator it = this->_ers.begin(); it != this->_ers.end(); ++it )
{
if( *it == er ) // 如发现重复的事件响应者,说明已绑定
{
unbound = false; break;
}
}
if( unbound )
this->_ers.push_back( er );
else
delete er.action, er.action = NULL;
}
// 解除事件绑定,删除事件响应者对象
template< typename Responsor, typename Action >
void Unbind( Responsor* actor, Action action ){
Action * act = new Action( action );
EventResponsor<EventAction> er( (Empty*)actor, (EventAction*)act); // 创建一个对象
for( EventIterator it = this-> _ers.begin(); it != this-> _ers.end(); ++it)
{
if(*it == er ) // 找到待删除的事件响应者对象
{
delete it->action, this->_ers.erase( it );
break;
}
}
delete er.action, er.action = NULL;
}
};
// 定义事件委托模型,指向类成员函数的指针
typedef Empty EventDelegator;
// 这其实定义的是函数指针类型
// 定义了和Actor的成员函数OnValueChanged一致的函数指针类型;完成了跨类的成员函数指针转换
typedef void ( EventDelegator::*ValueChanged)( int, void *);
class Trigger
{
public:
Trigger():_value(0) {}
void SetValue( int value, void * tag );
int GetValue() { return _value; }
public:
// 值变化事件,公开属性,方便在类外设定
Event<ValueChanged> value_changed;
private:
int _value;
};
// 设定值,遍历特定事件的响应时间列表,逐一触发值变更事件
void Trigger::SetValue( int value, void * tag){
if( _value == value ) return;
_value = value;
Event<ValueChanged>::EventResponsors ers;
ers = this->value_changed.GetResponsors();
if( !ers.empty() )
{
Event<ValueChanged>::EventIterator it;
for( it = ers.begin(); it != ers.end(); ++it)
{
(( it->actor)->*(*(it->action)))(value, tag); // 响应事件
}
}
}
// 行动者
class Actor
{
public:
// 侦听事件,绑定本对象的事件响应函数到侦听的事件
void Listen( Trigger * trigger)
{ trigger->value_changed.Bind( this, &Actor::OnValueChanged ); }
void UnListen( Trigger * trigger )
{ trigger->value_changed.Unbind( this, &Actor::OnValueChanged );}
// 值变更事件的响应函数
void OnValueChanged( int value, void * tag )
{ cout << reinterpret_cast<char*>(tag) << value << "." << endl;}
};
// 以下是main.cpp文件中的内容
#include "Event.hpp"
int main(){
const char * s = "Now the value is ";
Trigger t;
Actor a1,a2; // 创建事件响应者
a1.Listen( &t );
a2.Listen( &t );
cout << "Listening..." << endl;
t.SetValue( 10, reinterpret_cast<void*>(const_cast<char*>(s)));
a2.UnListen( &t );
cout << "Listening again..." << endl;
t.SetValue( 20, reinterpret_cast<void*>( const_cast<char*>(s)));
return 0;
}
版本二:直接使用指向类成员函数的指针,即一级指针;这一版是我的改进,因为分析发现,构建二级指针没有必要
#pragma once
#include <iostream>
#include <vector>
using namespace std;
// 空类,用于指代响应者对象
class Empty {};
// 事件响应者模板,保存特定事件的响应者与响应行为
template<typename EventAction>
class EventResponsor{
public:
EventResponsor(): actor(NULL), action(NULL) {
cout << "Constructor called!" << endl;
}
EventResponsor(Empty* actor, EventAction action):actor(actor), action(action) {
cout << "Non-default Constructor called!" << endl;
}
EventResponsor(const EventResponsor & obj):actor(obj.actor),action(obj.action) {
cout << "Copy Constructor called!" << endl;
}
EventResponsor & operator = ( const EventResponsor & obj ){
this->actor = obj.actor, this->action = obj.action;
cout << "Copy Assignment called!" << endl;
return *this;
}
friend bool operator == (const EventResponsor& lhs, const EventResponsor& rhs)
{return lhs.actor == rhs.actor && (lhs.action) == (rhs.action);}
public: // 公开数据成员,以方便使用者
Empty* actor;
EventAction action; // 一级指针:NONO ~~~~注意:EventAction本身就是一个指向类的成员函数的指针
};
// 事件类模板,用于管理特定事件的所有响应者
template< typename EventAction >
class Event{
public:
// 类型定义
typedef vector<EventResponsor<EventAction> > EventResponsors;
typedef typename vector<EventResponsor<EventAction> >::iterator EventIterator;
private:
EventResponsors _ers;
public:
virtual ~Event(){
/*
for(EventIterator it = this->_ers.begin(); it != this->_ers.end(); ++it){
delete it->action;
it->action = nullptr;
}
*/
}
EventResponsors & GetResponsors() { return this->_ers; }
// 事件绑定,将实际响应者和响应行为挂接到事件响应者对象上
template< typename Responsor, typename Action > // 模板类里面套模板函数
void Bind( Responsor* actor, Action action ){
// Action* act = new Action( action );
EventResponsor< EventAction > er((Empty*)actor, (EventAction)action); // 创建了事件响应对象
bool unbound = true;
for( EventIterator it = this->_ers.begin(); it != this->_ers.end(); ++it )
{
if( *it == er ) // 如发现重复的事件响应者,说明已绑定
{
unbound = false; break;
}
}
if( unbound )
this->_ers.push_back( er );
//else
//delete er.action, er.action = NULL;
}
// 解除事件绑定,删除事件响应者对象
template< typename Responsor, typename Action >
void Unbind( Responsor* actor, Action action ){
//Action * act = new Action( action );
EventResponsor<EventAction> er( (Empty*)actor, (EventAction)action); // 创建一个对象
for( EventIterator it = this-> _ers.begin(); it != this-> _ers.end(); ++it)
{
if(*it == er ) // 找到待删除的事件响应者对象
{
this->_ers.erase( it );
break;
}
}
//delete er.action, er.action = NULL;
}
};
// 定义事件委托模型,指向类成员函数的指针
typedef Empty EventDelegator;
// 这其实定义的是函数指针类型
// 定义了和Actor的成员函数OnValueChanged一致的函数指针类型;完成了跨类的成员函数指针转换
typedef void ( EventDelegator::*ValueChanged)( int, void *);
class Trigger
{
public:
Trigger():_value(0) {}
void SetValue( int value, void * tag );
int GetValue() { return _value; }
public:
// 值变化事件,公开属性,方便在类外设定
Event<ValueChanged> value_changed;
private:
int _value;
};
// 设定值,遍历特定事件的响应时间列表,逐一触发值变更事件
void Trigger::SetValue( int value, void * tag){
if( _value == value ) return;
_value = value;
Event<ValueChanged>::EventResponsors ers;
ers = this->value_changed.GetResponsors();
if( !ers.empty() )
{
Event<ValueChanged>::EventIterator it;
for( it = ers.begin(); it != ers.end(); ++it)
{
(( it->actor)->*(it->action))(value, tag); // 响应事件
}
}
}
// 行动者
class Actor
{
public:
// 侦听事件,绑定本对象的事件响应函数到侦听的事件
void Listen( Trigger * trigger)
{ trigger->value_changed.Bind( this, &Actor::OnValueChanged ); }
void UnListen( Trigger * trigger )
{ trigger->value_changed.Unbind( this, &Actor::OnValueChanged );}
// 值变更事件的响应函数
void OnValueChanged( int value, void * tag )
{ cout << reinterpret_cast<char*>(tag) << value << "." << endl;}
};
int main(){
const char * s = "Now the value is ";
Trigger t;
Actor a1,a2; // 创建事件响应者
a1.Listen( &t );
a2.Listen( &t );
cout << "Listening..." << endl;
t.SetValue( 10, reinterpret_cast<void*>(const_cast<char*>(s)));
a2.UnListen( &t );
cout << "Listening again..." << endl;
t.SetValue( 20, reinterpret_cast<void*>( const_cast<char*>(s)));
return 0;
}
运行结果: