[英]C++ Curiously recurring template pattern, syntax error
我試圖編寫一個模板事件類,並在此基類中保留盡可能多的代碼。 我正在使用反復出現的模板模式,但是我不確定我在這里做什么。
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;
};
以及給定事件類型的子類:
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 );
}
};
還有一個實現監聽器類的類:
class MyClass : public ConnectionSuccessEvent::Listener
{
public:
void OnConnectionSuccess( ConnectionSuccessEvent::Data * pEventData )
{
std::cout << "OnConnectionSuccess : " << pEventData->m_iVal << std::endl;
}
};
我使用如下:
MyClass oMyClassInstance;
ConnectionSuccessEvent oOnConnectionSuccess;
oOnConnectionSuccess += & oMyClassInstance;
oOnConnectionSuccess += & oMyClassInstance;
ConnectionSuccessEvent::Data oData( 456 );
oOnConnectionSuccess.Trigger( & oData );
oOnConnectionSuccess -= & oMyClassInstance;
oOnConnectionSuccess -= & oMyClassInstance;
這導致了幾個編譯錯誤,第一個是:
錯誤2錯誤C2059:語法錯誤:'>'c:\\ dev \\ eventtest \\ event.h 16
對應於向量m_aListeners的聲明。
我有兩個問題:
是什么導致我的錯誤? 我不能在類Event中使用EventType :: Listener嗎?
奇怪的重復模式怎么可能? 我的意思是,要定義,派生類需要定義其父類。 但是因為它是父類,所以它的父類需要定義其模板參數類(即它的基類),所以這是一個問題,因為要定義一個,首先需要定義另一個。 這就像在類B中有一個實例A,在類A中有一個實例obB。
謝謝 !
編輯:我不能使用C ++ 11。
我找到了一個可以接受的丑陋方法!
包含事件對象行為的基本事件類。
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 );
}
};
和:
template< class EventDataType >
class EventListener
{
public:
virtual ~EventListener() { }
virtual void OnEvent( const EventDataType * pData ) = 0;
};
ConnectionSuccessEvent特定的東西:
class ConnectionSuccessEventData
{
public:
const int m_iVal;
ConnectionSuccessEventData( int iVal ) : m_iVal( iVal ) { }
};
typedef EventListener< ConnectionSuccessEventData > ConnectionSuccessEventListener;
typedef BaseEvent< ConnectionSuccessEventListener, ConnectionSuccessEventData > ConnectionSuccessEvent;
DataReceivedEvent特定內容:
class DataReceivedEventData
{
public:
const float m_fVal;
DataReceivedEventData( float fVal ) : m_fVal( fVal ) { }
};
typedef EventListener< DataReceivedEventData > DataReceivedEventListener;
typedef BaseEvent< DataReceivedEventListener, DataReceivedEventData > DataReceivedEvent;
偵聽器類:
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;
}
};
用法:
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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.