Я сейчас перехожу из C# в C++, и я постоянно нажимаю дорожные блоки. Я получил систему обработки событий из учебника и попытаться адаптировать его к моим потребностям, но есть ошибка, которую я не могу понять:Шаблон обработчика событий: нерешенный внешний
Событие:
#pragma once
class Event
{
protected:
virtual ~Event() {};
};
Событие Hander:
#pragma once
#include "Event.h"
#include "TypeInfo.h"
#include "HandlerFunctionBase.h"
#include <map>
#include <typeindex>
class EventHandler
{
public:
void HandleEvent(const Event*);
template < class T, class EventT >
void RegisterEventFunc(T*, void (T::*memFn)(EventT*));
private:
typedef std::map<std::type_index, HandlerFunctionBase* > Handlers;
Handlers _handlers;
};
[...]
#include "EventHandler.h"
template < class T, class EventT >
void EventHandler::RegisterEventFunc(T* obj, void (T::*memFn)(EventT*))
{
_handlers[std::type_index(typeid(EventT))]=
new MemberFunctionHandler< T, EventT >(obj, memFn);
}
void EventHandler::HandleEvent(const Event* event)
{
Handlers::iterator it = _handlers.find(std::type_index(typeid(*event)));
if(it != _handlers.end())
{
it->second->exec(event);
}
}
HandlerFunctionBase:
#pragma once
#include "Event.h"
class HandlerFunctionBase
{
public:
virtual ~HandlerFunctionBase() {};
void exec(const Event* event) {call(event);}
private:
virtual void call(const Event*) = 0;
};
MemberFunctionHandler:
#pragma once
#include "handlerfunctionbase.h"
template < class T, class EventT >
class MemberFunctionHandler : public HandlerFunctionBase
{
public:
typedef void (T::*MemberFunc)(EventT*);
MemberFunctionHandler(T* instance, MemberFunc memFn) : _instance(instance), _function(memFn) {};
void call(const Event* event)
{
(_instance->*_function)(static_cast< EventT* >(event));
}
private:
T* _instance;
MemberFunc _function;
};
LogHandler
(Мой собственный класс, сначала попробуйте использовать систему)
#pragma once
#include "EventHandler.h"
#include "LogEvent.h"
class LogHandler
{
public:
LogHandler(EventHandler*);
~LogHandler(void);
private:
void Handle(LogEvent*);
};
#[...]
#include "LogHandler.h"
LogHandler::LogHandler(EventHandler *handler)
{
//This line causes the error
handler->RegisterEventFunc<LogHandler, LogEvent>(this, &LogHandler::Handle);
}
LogHandler::~LogHandler(void)
{
}
void LogHandler::Handle(LogEvent* e)
{
}
Что я получаю при попытке компиляции это:
Ошибка 1 ошибка LNK2019: неразрешенный внешний символ "public: void __thiscall EventHandler :: RegisterEventFunc (класс LogHandler *, void (__thiscall LogHandler :: *) (класс LogEvent *))" (?? $ RegisterEventFunc @ VLogHandler @@ VLogEvent @@ @ EventHandler @@ QAEXPAVLogHandler @@ P81 @ AEXPAVLogEvent @@@ Z @ Z), на которые ссылается функция «public: __thiscall LogHandler :: LogHandler (класс EventHandler *)» (? 0LogHandler @@ QAE @ PAVEventHandler @@@ Z) D: \ Dropbox \ C++ \ D-Tris \ D-Tris \ D-Tris \ LogHandler.obj D-Tris
Как не разрешен RegisterEventFunc? Это ясно реализовано!?
Вам нужно поместить реализацию шаблонного метода в файл заголовка. – v154c1
Являются ли ваши определения функций шаблонов в .cpp-файле? Если это так, вы должны сделать их доступными для кода, который создает шаблоны. На практике самый простой способ сделать это - поместить их в файл заголовка. – juanchopanza
Я делаю? ЗАЧЕМ? Я думал, что C++ игнорирует файлы и просто сшивает все вместе!? – pixartist