gpt4 book ai didi

c++ - 不同模板类型的多重继承

转载 作者:行者123 更新时间:2023-11-30 03:11:48 25 4
gpt4 key购买 nike

我正在使用 C++ 处理事件并处理事件通知,我有一个 EventGenerator 类,任何生成事件的类都可以从该类继承。 EventGenerator 有一个其他类可以用来添加回调的方法和一个事件发生后调用回调的方法

为了处理不同类型事件的通知,我在模板类型 T 上参数化了 EventGenerator,然后通知程序类可以从 EventGenerator 继承多次不同类型的参数化。

为了完整起见,这里是 EventGenerator 的代码

#ifndef _EventGenerator
#define _EventGenerator

#include <list>

#include "EventListener.h"

template <class Event>
class EventGenerator {
private:
std::list<EventListener<Event>*> listeners;
protected:
EventGenerator() {}

void changeEvent(Event event) {
std::list<EventListener<Event>*>::const_iterator it = listeners->begin();
for (; it != listeners->end(); it++) {
(*it)->changeEvent(event);
}
}

public:
void addListener(EventListener<Event>* listener) {
listeners->push_back(listener);
}
};

#endif



这是 EventListener 的代码,任何想要添加回调的类都继承自 -

#ifndef _EventListener
#define _EventListener

template <class Event>
class EventListener {
private:
EventListener(const EventListener<Event>& event);
protected:
EventListener() {}
public:
virtual void changeEvent(Event event) = 0;
};

#endif



我觉得这不是一个很好的设计,想知道是否有更好的设计来解决这样的问题。

编辑:令我烦恼的是我正在使用多重继承。我经常被警告不要使用它,所以我想我想知道这样的设计是否会导致 future 发生不好的事情

谢谢

最佳答案

当心菱形继承层次结构。另请注意,重载虚函数是一件坏事。所以如果你有这样的事情:

class Handler : public EventHandler<int>, public EventHandler<string> { ... };

将调用哪个 changeEvent() 函数?不要指望它!

如果你很小心,上面的代码应该没问题,但如果你想完全避免继承,那么我建议使用与一些唯一标识符相关联的函数引用。例如:

class Listener { public: virtual ~Listener ( ) { } };
template<typename Event> class Distributor : public Listener {
public:
void addListener (shared_ptr<Listener>, function<void (Event)>);
void listen (Event e) {
for_each(_listeners.begin(), _listeners.end(),
bind(&ListenNode::listen, _1, e));
}
private:
struct ListenNode {
weak_ptr<Listener> listener;
function<void (Event)> callback;
void listen (Event e) {
shared_ptr<Listener> l = listener.lock();
if(l) callback(e);
}
};
list<ListenNode> _listeners;
};

使用此设置,所有监听器实际上都派生自一个基类。 Listeners 可以注册多个回调,Distributors 可以链接起来。当然,您不必使用 shared_ptr,但我喜欢它们,因为它们省去了注销监听器的麻烦。您可以按照自己喜欢的方式注册回调,将它们与字符串、整数或其他任何内容相关联。

我省略了很多细节,事件分发是一项复杂的业务。我认为 Andrei Alexandrescu 写了一篇关于该主题的详细文章,请查阅。

关于c++ - 不同模板类型的多重继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1967283/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com