Это не должен быть сайт проверки кода, но я ничего не могу с собой поделать ...
// "CEvents.h"
class CEvents
{
public:
typedef void (*Callback)(void);
// 1. Don't use `using namespace` in header files
// 2. Pass by const reference to avoid a copy
// 3. Function Pointers are easier to deal with when typedef'd
void Add(std::string const& EventName, Callback fn);
void Remove(std::string const& EventName, Callback fn);
void Trigger(std::string const& EventName);
// Attributes should be `private` or `public`, `protected` is for functions.
// If you read otherwise, consider how this violates encapsulation.
//protected:
private: // cause nobody's touching my stuff lest they break it!
// useless in this class, should be local variables in the routines
// bool Found;
// MapType::iterator EvMapIt;
// typedef make life easier, spelling that out each time is just tiring.
typedef std::multimap<std::string, Callback> MapType;
MapType EventsMap;
};
Хорошо, давайте перейдем к исходному файлу.
//CEvents.cpp
// Whole rewrite to use idiomatic interfaces
void CEvents::Add(std::string const& EventName, Callback fn)
{
// Retrieve the range of callbacks registered for "EventName"
std::pair<MapType::iterator, MapType::iterator> const range =
EventsMap.equal_range(EventName);
// Check that this callback is not already registered.
for (MapType::iterator it = range.first, end = range.second;
it != end; ++it)
{
if (it->second == fn) {
// Are you sure `ErrorOut` should not be a free function
// or at least a `static` function ?
// It feels weird instantiating this class.
CTools tools;
tools.ErrorOut("Function already bound to same event..."
" Not registering event");
// If it is in there, nothing to do, so let's stop.
return;
}
}
// If we are here, then we need to add it.
// Let's give a hint for insertion, while we are at it.
EventsMap.insert(range.second, std::make_pair(EventName, fn));
// the (int) cast was C-like (bah...) and unnecessary anyway
std::cout << "Added, with size " << EventsMap.size() << std::endl;
}
void CEvents::Trigger (std::string const& EventName)
{
std::cout << "Triggering init" << std::endl;
std::cout << EventsMap.size() << std::endl; //Getting 0
// Retrieve the range of callbacks registered for `EventName`
std::pair<MapType::const_iterator, MapType::const_terator> const range =
EventsMap.equal_range(EventName);
// Call each callback in turn
for (MapType::const_iterator it = range.first, end = range.second;
it != end; ++it)
{
it->second();
}
}
Конечно, это может не решить вашу проблему, но она намного короче, чем должна помочь сузить ее.
Конечно, может быть проще использовать std::set<std::pair<std::string, Callback>>
, потому что он автоматически обеспечит уникальность пар (EventName, fn)
... хотя код для отправки события будет немного сложнее, поэтому не уверен, что это выигрыш (с точки зрения кода или производительности).