我正在创建一个简单的事件系统,多个监听器可以在特定主题上接收通知,当事件被触发时,它可以将通用有效载荷传递给事件,并且监听器将匹配已触发事件的格式。然而,由于虚函数无法使用模板,那么我该如何实现这一点呢?
class AEventListener
{
public:
template<class T>
struct PayloadObject {
T obj;
};
explicit AEventListener();
virtual ~AEventListener();
//error here because T is undefined. Each PayloadObject may have a different type
virtual void notify(vector<shared_ptr<PayloadObject<T>>> payload) = 0;
};
当事件主题有一个已订阅的侦听器时,将调用notify方法,但我想以通用的方式将一堆随机对象传递给侦听器。
例如
fireEvent("test.topic", Payload { 0, "hello", 123 });
//...
listener.notify(payload);
我该如何在C++中实现这一点?
虽然我设法绕过了这个问题,但我认为这不是最好的方法,可能会降低性能。
template<class T>
struct PayloadObject : public APayloadObject {
T obj;
PayloadObject(T obj) {
this->obj = obj;
}
~PayloadObject() override {
};
};
struct APayloadObject {
virtual ~APayloadObject();
};
触发:
vector<shared_ptr<APayloadObject>> payload;
payload.push_back(shared_ptr<PayloadObject<int>>(new PayloadObject<int>(5))); //payload[0] = int - 5
Events::fire(EventKeys::DISCONNECTION_EVENT, payload);
通知:
shared_ptr<PayloadObject<int>> number = dynamic_pointer_cast<PayloadObject<int>>(payload[0]);
int id = number.get()->obj; //payload[0] = int - 5
shared_ptr
构造函数内部使用make_shared
而不是使用new
。 - bartopmake_shared
只进行一次堆分配,而new
版本则需要进行两次 - 第一次为对象,第二次为控制块。在这种情况下使用new
也可能导致意外的内存泄漏。这篇帖子:https://dev59.com/fGMl5IYBdhLWcg3wkXpx 给出了相当清晰的答案。 - bartop