C++模拟Event和Delegate

本文通过C++实现事件和委托功能,展示了如何在MiniPage类中挂接Button并触发事件,进而调用预设的回调函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

         C++作为一门像瑞士军刀一样的编程语言很灵活很强大,可以使用它来实现其他语言有的特性。以下代码将用例子来展示一个用C++来实现事件和委托类似的功能,在我们的MiniPage类里面挂接一个Button,当有Button的点击事件发生的时候,通过委托来调用我们自己写好的回调函数。

首先, Event.h里定义我们需要的事件和委托类型

#ifndef _EVENT_H
#define _EVENT_H

#include <vector>
#include <algorithm>

// define virtual handler for event
template<class AT>class EventHandler
{
public:
	virtual ~EventHandler(){}
	virtual void operator()( AT& )=0;
};

// specific handler , event delegate 
template< class T, class AT >
class EventDelegate : public EventHandler<AT>
{
private:
	typedef T ClassType;
	typedef AT ArgsType;
	typedef void ( ClassType::*Handler )( AT& args ); 
public:
	EventDelegate( ClassType* target, Handler handler )
		: _target(target)
		, _Handler(handler)
	{
	}

	~EventDelegate(){}

	virtual void operator()(AT& agrs )
	{
		( _target->*_Handler )(agrs);
	}

private:
	EventDelegate();
	EventDelegate( const EventDelegate& );
	EventDelegate& operator=( const EventDelegate& );
	ClassType*	<span style="white-space:pre">	</span>_target;
	Handler		<span style="white-space:pre">	</span>_Handler;
};

// one event <-- many handlers
template<class AT >class Event
{
private:
	typedef AT	AgrsType;
	typedef Event< AgrsType >  ThisType;
	typedef EventHandler< AgrsType > HandlerType;
	typedef std::vector<HandlerType*> HandlerList;
	typedef typename HandlerList::iterator	HandlerIterator;	// typename is important !
public:
	Event(){}
	~Event()
	{
		HandlerIterator itr	= mHandlerList.begin();
		for( ; itr != mHandlerList.end(); ++itr )
		{
			delete *itr;
		}
		mHandlerList.clear();
	}

	ThisType& operator+=( EventHandler<AgrsType>* handler )
	{
		HandlerIterator itr;
		itr	= std::find( mHandlerList.begin(), mHandlerList.end(), handler );
		if ( itr == mHandlerList.end() )
		{
			mHandlerList.push_back( handler );
		}
		return *this;
	}
	ThisType& operator-=( EventHandler<AgrsType>* handler )
	{
		HandlerIterator itr;
		itr	= std::find( mHandlerList.begin(), mHandlerList.end(), handler );
		if ( itr != mHandlerList.end() )
		{
			mHandlerList.erase( handler );
		}
		return this;
	}
	void operator()( AgrsType& agrs )
	{
		HandlerIterator itr	= mHandlerList.begin();
		while ( itr != mHandlerList.end() )
		{
			(*(*itr))(agrs);
			++itr;
		}
	}
private:
	HandlerList	<span style="white-space:pre">	</span>mHandlerList;
};
#endif//_EVENT_H

再来,ControlButton.h 定义用于触发事件的控件按钮

#ifndef _CONTROL_BUTTON_H
#define _CONTROL_BUTTON_H
#include "Event.h"

class ControlButton;

// agrs tell us witch obj's event occurs;
class ButtonTouchAgrs
{
public:
	ButtonTouchAgrs();
	ControlButton* getButton()const		{ return mButton; }
	void setButton( ControlButton* button ) { mButton	= button; }

private:
	ControlButton*	<span style="white-space:pre">	</span>mButton;
};

typedef  Event<ButtonTouchAgrs>	EventType;

class ControlButton
{
public:
	ControlButton();
	~ControlButton();

	template< class TargetT, class AT >
	void setPressEventHandler( EventDelegate<TargetT, AT>* handler )
	{
		mPressEvent			+= handler;
	}

	template< class TargetT, class AT >
	void setReleaseEventHandler( EventDelegate<TargetT, AT>* handler )
	{
		mReleaseEvent		+= handler;
	}

	void doButtonCheck( int index );

private:
	EventType		mPressEvent;		// specific event
	EventType		mReleaseEvent;
};
#endif //_CONTROL_BUTTON_H

ControlButton.cpp

#include "ControlButton.h"

ButtonTouchAgrs::ButtonTouchAgrs()
{
	mButton	= 0;
}

ControlButton::ControlButton()
{
}

ControlButton::~ControlButton()
{
}

void ControlButton::doButtonCheck( int times )
{
	ButtonTouchAgrs agrs;
	agrs.setButton( this );

	if ( 3 == times )	 // means touch event occurs when times is 3 sec
	{
		mPressEvent( agrs);
	}
	else if( 5 == times )<span style="white-space:pre">	</span>// means release event occurs when times is 5 sec
	{
		mReleaseEvent( agrs );
	}
}


接着,我们需要定义挂载button的MiniPage类,在该类型里定义我们需要的事件回调函数

#ifndef _MINI_PAGE_H
#define _MINI_PAGE_H

#include "ControlButton.h"

class MiniPage
{
public:
	MiniPage(): mButton(NULL){}
	~MiniPage();
	void initPage();

	// define callback methods
	void onButtonPress( ButtonTouchAgrs& args );
	void onButtonRelease( ButtonTouchAgrs& args );

	ControlButton* getButton() const { return mButton; }

private:
	ControlButton*<span style="white-space:pre">	</span>		mButton;
};

#endif	//_MINI_PAGE_H

MiniPage.Cpp

#include "MiniPage.h"

MiniPage::~MiniPage()
{
	if ( mButton )
	{
		delete mButton;
		mButton	= NULL;
	}
}

void MiniPage::initPage()
{
	mButton	= new ControlButton;

	mButton->setPressEventHandler( new EventDelegate<MiniPage, ButtonTouchAgrs>( this, &MiniPage::onButtonPress ) );
	mButton->setReleaseEventHandler( new EventDelegate<MiniPage, ButtonTouchAgrs>( this, &MiniPage::onButtonRelease ) );
}

void MiniPage::onButtonPress( ButtonTouchAgrs& args )
{
	printf( "button press callback method\n ");
}

void MiniPage::onButtonRelease( ButtonTouchAgrs& args )
{
	printf( "button release callback method\n ");
}


        最后,我们需要一个用例,来测试我们在MiniPage挂载的ControlButton在指定的时间到达后,是否会触发相应的事件,并调用在MiniPage里面定义的回调函数

main.cpp

/** created by Luo Zheng@chengdu 2014.8.16 **/
/*
 this project used to simulate the Delegate & Event :
 when times is 3, touch button and run the callback "onButtonPress"
 when times is 5, release button and run the callback "onButtonRelease"
*/

#ifndef _MAIN_H
#define _MAIN_H
#include <time.h>
#include "MiniPage.h"

int gTime		= 0;
int deltaTime	= 0;

int main()
{
	MiniPage*	miniPage	= new MiniPage;
	miniPage->initPage();

	gTime		= time( 0 );
	int temp	= 0;
	while( true )
	{
		temp	= time( 0 );
		if ( 1 <= temp - gTime )
		{
			gTime	= temp;
			++deltaTime;
			miniPage->getButton()->doButtonCheck(deltaTime);
		}
	}
	return 0;
}

#endif //_MAIN_H

最后的结果,说明我们定义的事件被触发,并通过委托类型调用了我们先注册的回调函数.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值