与其中包含的类相同类型的列表

时间:2016-05-18 20:26:45

标签: c++

我正在尝试创建一个简单的事件系统,它将有许多不同的事件。所以,我试图创建一个事件类,它允许你注册函数,获取正确的事件类型,并返回一个布尔值。

我想要的是post的任何子类中的方法Event将采用该子类而不是Event,并且每个子类中的列表listeners中的函数应该采用正确的子类类型。这是我已经拥有的代码,它强制函数转换为正确的事件类型:

events.h:

namespace events {
    class Event {
        public:
            static const std::List<bool (*)(Event)> listeners;
            void post(Event event);
    }

    class ExampleEvent : Event {
        int eventData;
    }
}

events.cpp:

namespace events {
    void Event::post(Event event) {
        for(int i = 0; i < listeners.size(); i++) {
            if(listeners[i](event)) return;
        }
    }
}

有什么方法可以让我使用子类化事件而不必执行以下操作?

bool handleExample(Event event) {
    ExampleEvent exampleEvent = (ExampleEvent)event;
    std::cout << exampleEvent.eventData << std::endl;
    return false;
}

// Somewhere else in the code
ExampleEvent::listeners.push_back(&handleExample);

我为任何不正确的代码道歉,我还没有完善的语言规则。

2 个答案:

答案 0 :(得分:0)

常见的方法是使用CRTP:

namespace events {
    template<typename Derived>
    class Event {
        public:
            static const std::list<bool (*)(Derived)> listeners;
            void post(Derived event)
            {
                 static_cast<Derived&>(*this).post(event);
            }
    };

    class ExampleEvent : Event<ExampleEvent> {
        int eventData;
        void post(ExampleEvent event)
        {
             //implement post
        }
    };
}

答案 1 :(得分:0)

只需使用虚拟功能:

namespace events {
    class EventHandler {
        public:
            static const std::list<Event*> listeners;
            void post() {
                for (Event * listener : listeners) {
                   if (listener->post()) break;
                }
            }
    };

    class BaseEvent {
    public:
       virtual bool post() = 0;
       virtual ~BaseEvent() {}
    };

    class ExampleEvent : public BaseEvent { // use public inheritance
        int eventData;
    public:
        virtual bool post() override {
           if (eventData == 0) return true;
           return false;
        }
    };
}