下面您可以看到我的简单事件分派器的实现。我想得到一些有关设计的反馈或改进建议,也许还有一个如何摆脱static_cast的想法。非常感谢。
#pragma once
#include <cstdint>
enum class EventType : uint8_t {
ButtonPress,
FactoryReset
};
class Event {
public:
Event() = default;
explicit Event(EventType type) : mType(type) {}
virtual ~Event() = default;
inline const EventType Type() const { return this->mType; };
protected:
EventType mType;
};#pragma once
#include "Event.h"
class ButtonPressEvent final : public Event {
public:
ButtonPressEvent(uint8_t pin) : Event(EventType::ButtonPress), mPin(pin) {};
uint8_t mPin;
};#pragma once
#include "Event.h"
class FactoryResetEvent final : public Event {
public:
FactoryResetEvent() : Event(EventType::FactoryReset) {};
};#pragma once
#include <functional>
#include <map>
#include <memory>
#include "Event.h"
using EventHandlerType = std::function<void(std::unique_ptr<Event>&)>;
class Subscriber {
public:
virtual ~Subscriber() = default;
virtual std::map<EventType, EventHandlerType> GetSubscribedEvents() = 0;
};#pragma once
#include <map>
#include <memory>
#include <vector>
#include "Event.h"
#include "Subscriber.h"
class Dispatcher {
public:
Dispatcher();
void Listen(EventType type, const EventHandlerType &funct);
void Subscribe(Subscriber *subscriber);
void Post(std::unique_ptr<Event> &ptr);
void Process();
private:
std::map<EventType, std::vector<EventHandlerType>> mObservers;
std::vector<std::unique_ptr<Event>> mEvents;
};#include "Dispatcher.h"
void Dispatcher::Listen(EventType type, const EventHandlerType &funct) {
this->mObservers[type].push_back(funct);
}
void Dispatcher::Subscribe(Subscriber *subscriber) {
for (auto&& event : subscriber->GetSubscribedEvents()) {
this->Listen(event.first, event.second);
}
}
void Dispatcher::Post(std::unique_ptr<Event> &ptr) {
this->mEvents.push_back(std::move(ptr));
}
void Dispatcher::Process() {
if (this->mEvents.empty()) {
return;
}
for (auto&& event : this->mEvents) {
// call listener functions
for (auto&& observer : this->mObservers.at(event->Type())) {
observer(event);
}
}
this->mEvents.clear();
}#pragma once
#include "Subscriber.h"
class App : public Subscriber {
public:
std::map<EventType, EventHandlerType> GetSubscribedEvents();
void OnButtonPressEvent(std::unique_ptr<Event> &event);
};#include <functional>
#include <stdio.h>
#include "App.h"
#include "Event.h"
#include "ButtonPressEvent.h"
std::map<EventType, EventHandlerType> App::GetSubscribedEvents() {
return {
{ EventType::ButtonPress, std::bind(&App::OnButtonPressEvent, this, std::placeholders::_1) }
};
}
void App::OnButtonPressEvent(std::unique_ptr<Event> &event) {
ButtonPressEvent *b = static_cast<ButtonPressEvent*>(event.get());
printf("Button pin %d pressed", b->mPin);
}#include "Dispatcher.h"
#include "ButtonPressEvent.h"
#include "App.h"
void main(void) {
App app;
Dispatcher dispatcher;
dispatcher.Subscribe(&app);
// simulate event
std::unique_ptr<Event> ptr(new ButtonPressEvent(11));
dispatcher.Post(ptr);
while (true) {
dispatcher.Process();
}
}发布于 2021-12-11 20:09:09
与编码一致,目前使用的创建默认构造函数的策略不同。
中包含头文件
通过在头文件中包含头文件,代码可能会成为维护问题,并且在预处理器运行后编译的代码的大小可能不必要地膨胀。维护代码的人在修改C++源文件时可能不会查看头文件。这还可能减少头文件更改时需要编译的文件数。
通常,在C++中,不需要使用this对象来指向成员变量或方法。只需使用名称即可访问成员。在Dispatcer.cpp中,不需要使用this。在您使用的编译器中,它可能是必要的,因为构造函数没有定义。在头文件FactorResetEvent.h中,构造函数也可以是默认构造函数。
#include "Dispatcher.h"
void Dispatcher::Listen(EventType type, const EventHandlerType& funct) {
mObservers[type].push_back(funct);
}
void Dispatcher::Subscribe(Subscriber* subscriber) {
for (auto&& event : subscriber->GetSubscribedEvents()) {
Listen(event.first, event.second);
}
}
void Dispatcher::Post(std::unique_ptr<Event>& ptr) {
mEvents.push_back(std::move(ptr));
}
void Dispatcher::Process() {
if (mEvents.empty()) {
return;
}
for (auto&& event : mEvents) {
// call listener functions
for (auto&& observer : this->mObservers.at(event->Type())) {
observer(event);
}
}
mEvents.clear();
}如果不为对象(如Dispatcher )创建构造函数,则可以将构造函数定义为默认构造函数。在Subscriber.h中使用默认析构函数,但根本没有定义构造函数。
class Dispatcher {
public:
Dispatcher() = default;
void Listen(EventType type, const EventHandlerType& funct);
void Subscribe(Subscriber* subscriber);
void Post(std::unique_ptr<Event>& ptr);
void Process();
private:
std::map<EventType, std::vector<EventHandlerType>> mObservers;
std::vector<std::unique_ptr<Event>> mEvents;
};我的编译器和链接器(Visual 2019)报告说,当我编译程序时,构造函数是未定义的。
https://codereview.stackexchange.com/questions/270907
复制相似问题