将基类传递给继承超类的函数委托

时间:2020-04-12 13:55:02

标签: c++ oop

我有这张地图: map<IEvent, EventHandler, IEventCompare> EventHandler被定义为typedef void (*EventHandler)(IEvent);

IEvent是描述一般事件的类。

现在,我想向此映射添加一个函数,该函数接收CreationEvent,该类继承了IEvent。该函数的定义如下:

void onCreate(CreationEvent);

但是当我尝试将其添加到地图时,出现编译错误

E0167 argument of type "void (Engine::IObject::*)(Engine::CreationEvent)" is incompatible with parameter of type "Engine::EventHandler" 

如果我尝试将其明确转换为EventHandlerE0171 invalid type conversion

我可以用onCreate声明IEvent,但是我想避免使用它,因为这将要求我假设事件的类型,而且定义不明确。

有没有办法做我尝试的事情?

IEvent:

/**
    * Represents an Event, such as collision between 2 objects or click on an object.
    */
    class IEvent
    {
    public:
        IEvent(string name) { this->name = name; };
        /**
        * Copy constructor.
        */
        IEvent(const IEvent& other) { this->name = other.name;};

        string getName() const { return this->name; };

    protected:
        string name;
    };

CreationEvent:

class CreationEvent : public IEvent
    {
    public:
        CreationEvent();

        std::chrono::time_point<std::chrono::system_clock> getCreateTime() const;

    private:
        std::chrono::time_point<std::chrono::system_clock> creationTime; /**< The creation time of this event.*/
    };

注意: 一切都在命名空间Engine中,并且映射在IObject内部声明。

1 个答案:

答案 0 :(得分:1)

如果我对您的想法正确,那么您想要:

  • 具有基类ID_NF的类型化事件。
  • 具有带有基类ID的处理程序。
  • 处理程序可以接收某种类型的事件。

考虑下一个示例。为简单起见,我使用event代替了handler,并将其放在事件类中。

此代码包含丑陋,泄漏,未经修改,不得在“产品”中使用。

std::vector

唯一棘手的部分是:

std::map

这里我们生成用于存储类型化的“回调”并使用多态性将这些类存储在std :: vector中的类,因为它们都是处理程序的子类。

建议-考虑使用智能指针而不是原始指针。另外,您可以将函数#include <iostream> #include <vector> //***********************************************************// struct event; struct handler { }; struct event_handler { event_handler(handler* receiver) : receiver_{ receiver } {} handler* receiver_; virtual void invoke(event& evt) = 0; }; template <typename T, typename U> struct event_handler_impl : event_handler { typedef void (T::* handler_function)(U&); event_handler_impl(handler* receiver, handler_function function) : event_handler{ receiver_ }, function_{ function } {} void invoke(event& evt) { T* typed_receiver = static_cast<T*>(receiver_); U& typed_event = static_cast<U&>(evt); (typed_receiver->*function_)(typed_event); } handler_function function_; }; struct event { void subscribe(event_handler* hdlr) { //TODO: Check. Is double added? handlers_.push_back(hdlr); } void sent() { for (auto& item : handlers_) { item->invoke(*this); } } std::vector<event_handler*> handlers_; }; //*****************************EXAMPLE***********************// struct creation_event : public event { int creation_id{}; }; struct bar_handler : public handler { void handle_creation(creation_event& evt) { std::cout << "bar" << evt.creation_id << std::endl; } }; struct foo_handler : public handler { void handle_creation(creation_event& evt) { std::cout << "foo" << evt.creation_id << std::endl; } }; template<typename T, typename U> void subscribe_to_event(U& evt, T* reciver, void (T::* handler_function)(U&)) { evt.subscribe(new event_handler_impl<T, U>(reciver, handler_function)); } int main() { creation_event evt; bar_handler bar; foo_handler foo; subscribe_to_event(evt, &foo, &foo_handler::handle_creation); subscribe_to_event(evt, &bar, &bar_handler::handle_creation); evt.sent(); evt.creation_id = 1; evt.sent(); return 0; } 放入处理程序基类,以便删除第二个参数,并将“ this”传递给event_handler_impl-template <typename T, typename U> struct event_handler_impl : event_handler