C++ Curiously recurring template pattern, syntax error
我正在尝试编写一个模板事件类,并在这个基类中尽可能多地保留代码。我正在使用奇怪的重复模板模式,但我不确定我在这里做什么。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | template< class EventType > class Event { protected: std::vector< EventType::Listener * > m_aListeners; public: void operator += ( EventType::Listener * pListener ) { m_aListeners.push_back( pListener ); } void operator -= ( EventType::Listener * pListener ) { std::vector< EventType::Listener * >::reverse_iterator revIter = m_aListeners.rbegin(); for( ; revIter != m_aListeners.rend(); ++revIter ) if( revIter == pListener ) { m_aListeners.remove( revIter ); break; } } void Trigger( EventType::Data * pData ) { std::vector< EventType::Listener * >::iterator iter = m_aListeners.begin(); for( ; iter != m_aListeners.end(); ++iter ) CallListenert( iter, pData ); } virtual void CallListener( EventType::Listener * pListener, EventType::Data * pData ) = 0; }; |
以及给定事件类型的子类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class ConnectionSuccessEvent : public Event< ConnectionSuccessEvent > { public: class Data { public: Data( int iVal ) : m_iVal( iVal ) { } public: const int m_iVal; }; class Listener { public: virtual ~Listener() { } virtual void OnConnectionSuccess( Data * pEventData ) = 0; }; void CallListener( Listener * pListener, Data * pData ) { pListener->OnConnectionSuccess( pData ); } }; |
以及实现侦听器类的类:
1 2 3 4 5 6 7 8 9 | class MyClass : public ConnectionSuccessEvent::Listener { public: void OnConnectionSuccess( ConnectionSuccessEvent::Data * pEventData ) { std::cout <<"OnConnectionSuccess :" << pEventData->m_iVal << std::endl; } }; |
我使用如下:
1 2 3 4 5 6 7 8 9 10 11 12 | MyClass oMyClassInstance; ConnectionSuccessEvent oOnConnectionSuccess; oOnConnectionSuccess += & oMyClassInstance; oOnConnectionSuccess += & oMyClassInstance; ConnectionSuccessEvent::Data oData( 456 ); oOnConnectionSuccess.Trigger( & oData ); oOnConnectionSuccess -= & oMyClassInstance; oOnConnectionSuccess -= & oMyClassInstance; |
这会导致几个编译错误,第一个错误是:
错误2错误C2059:语法错误:">"C:deveventstestevent.h 16
对应于向量m的声明。
我有两个问题:
是什么导致了我的错误?我是否不允许在我的类事件中使用EventType::Listener?
奇怪的循环模式是如何可能的?我的意思是,要定义派生类,它需要定义其父类。但由于它是父类,父类要求定义它的模板参数类,即它是基类),所以这是一个问题,因为要定义一个模板参数类,就需要先定义另一个模板参数类。这就像在类B中有一个A的实例,在类A中有一个OB B的实例。
谢谢您!
编辑:我不能使用C++ 11。
我找到了一个可以接受的丑陋的方法!
包含事件对象行为的基本事件类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | template< class EventListenerType, class EventDataType > class BaseEvent { private: std::vector< EventListenerType * > m_aListeners; public: void operator += ( EventListenerType * pListener ) { m_aListeners.push_back( pListener ); } void operator -= ( EventListenerType * pListener ) { // When nI is 0 and gets decremented (i.e would be < 0), it"underflows" and // becomes >= m_aListeners.size(), so we can detect that the last element (i.e // the first in position ) has been treated when nI >= m_aListeners.size(). for( size_t nI = m_aListeners.size() - 1; nI <= m_aListeners.size(); --nI ) { if( m_aListeners[ nI ] == pListener ) { m_aListeners.erase( m_aListeners.begin() + nI ); break; } } } void Trigger( EventDataType * pData ) { for( size_t nI = 0; nI < m_aListeners.size(); ++nI ) m_aListeners[ nI ]->OnEvent( pData ); } }; |
还有:
1 2 3 4 5 6 7 8 9 | template< class EventDataType > class EventListener { public: virtual ~EventListener() { } virtual void OnEvent( const EventDataType * pData ) = 0; }; |
连接成功事件特定内容:
1 2 3 4 5 6 7 8 9 | class ConnectionSuccessEventData { public: const int m_iVal; ConnectionSuccessEventData( int iVal ) : m_iVal( iVal ) { } }; typedef EventListener< ConnectionSuccessEventData > ConnectionSuccessEventListener; typedef BaseEvent< ConnectionSuccessEventListener, ConnectionSuccessEventData > ConnectionSuccessEvent; |
数据接收开发特定的内容:
1 2 3 4 5 6 7 8 9 | class DataReceivedEventData { public: const float m_fVal; DataReceivedEventData( float fVal ) : m_fVal( fVal ) { } }; typedef EventListener< DataReceivedEventData > DataReceivedEventListener; typedef BaseEvent< DataReceivedEventListener, DataReceivedEventData > DataReceivedEvent; |
侦听器类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class MyClass : public ConnectionSuccessEventListener, public DataReceivedEventListener { public: void OnEvent( const ConnectionSuccessEventData * pData ) { std::cout <<"Connection success event :" << pData->m_iVal << std::endl; } void OnEvent( const DataReceivedEventData * pData ) { std::cout <<"Data received event :" << pData->m_fVal << std::endl; } }; |
用途:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | MyClass oMyClassInstance; ConnectionSuccessEvent oOnConnectionSuccess; DataReceivedEvent oOnDataReceived; oOnConnectionSuccess += & oMyClassInstance; oOnDataReceived += & oMyClassInstance; oOnConnectionSuccess += & oMyClassInstance; oOnDataReceived += & oMyClassInstance; ConnectionSuccessEventData oConnectionSuccessData( 123 ); oOnConnectionSuccess.Trigger( & oConnectionSuccessData ); DataReceivedEventData oDataReceivedData( 0.0f ); oOnDataReceived.Trigger( & oDataReceivedData ); oOnDataReceived += & oMyClassInstance; oOnConnectionSuccess -= & oMyClassInstance; oOnDataReceived += & oMyClassInstance; oOnConnectionSuccess -= & oMyClassInstance; |