【发布时间】:2015-10-21 09:10:44
【问题描述】:
我想像这样编写一个类似 C# 的 C++ 事件类:
template< typename ListenerType >
class Event
{
private:
std::vector< ListenerType * > m_aListeners;
public:
void operator += ( ListenerType * pListener )
{
m_aListeners.push_back( pListener );
}
void operator -= ( ListenerType * pListener )
{
std::vector< ListenerType * >::reverse_iterator revIter = m_aListeners.rbegin();
for( ; revIter != m_aListeners.rend(); ++revIter )
if( revIter == pListener )
{
m_aListeners.remove( revIter );
break;
}
}
};
class DataReceivedEvent : public Event< DataReceivedListener >
{
public:
void Trigger( const byte_t * pData )
{
for( size_t nI = 0; nI < m_aListeners.size(); ++nI )
m_aListeners[ nI ]->OnDataReceived( pData );
}
}
问题在于它迫使我编写一个 Trigger 方法,该方法总是为每种事件类型执行相同的操作(迭代和调用处理程序),因为不同的事件可以有不同的参数列表,并且对于每个事件,关联的处理程序类型有一个具有特定名称的方法。
我对 C++11 了解不多,但我感觉可以避免使用模板为每种事件类型重写 Trigger 方法。 但是我不能使用 C++11,所以我想知道是否有一种方法,使用旧的 C++ 版本,以一种类型安全的方式来做到这一点。
编辑:我考虑过创建事件数据类的层次结构,即template< typename ListenerType >::Data 和DataReceivedEvent::Data : public template< typename ListenerType >::Data,这样我就可以拥有一个始终采用单个参数的触发器方法,即virtual void Trigger( const Data * pData )。但是我还是有问题,它需要在事件监听器中调用特定的方法。
【问题讨论】:
-
你可以使用 Boost 吗?因为那时您可以使用Boost function 和Boost bind 库。
-
@JoachimPileborg 感谢您之前的评论 (stackoverflow.com/questions/14189440/…)。 VS2005似乎支持它,所以我会看看这个。而且我不想使用 boost,因为我的目标平台是 Android(没问题)和 Windows CE(boost 不太支持)。
-
何不幸的是 VS2005 不支持函数和绑定 :( 但也许我仍然可以找到一种兼容的方法来处理
<functional>中存在的内容
标签: c++ class templates events