gpt4 book ai didi

c++ - 将基类传递给接收父类(super class)的函数委托(delegate)

转载 作者:行者123 更新时间:2023-12-02 10:18:18 24 4
gpt4 key购买 nike

我有这张 map :map<IEvent, EventHandler, IEventCompare>在哪里 EventHandler定义为 typedef void (*EventHandler)(IEvent);IEvent是描述一般事件的类。

现在我想在这个 map 中添加一个接收 CreationEvent 的函数。 , 一个继承 IEvent 的类.函数定义如下:
void onCreate(CreationEvent);
但是当我尝试将其添加到 map 时,出现编译错误

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

如果我尝试将其显式转换为 EventHandler : E0171 invalid type conversion
我可以声明 onCreateIEvent ,但我想避免它,因为它需要我假设事件的类型,并且它没有很好的定义。

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

事件:
/**
* 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;
};

创建事件:
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 ,并且 map 在 IObject 内声明.

最佳答案

如果我理解你的想法,你想要:

  • 输入了带有 event 基数的事件类(class)。
  • 拥有基数为 handler 的处理程序类(class)。
  • 处理程序可以接收某种类型的事件。

  • 考虑下一个例子。为简单起见,我使用了 std::vector而不是 std::map ,并将其放在事件类中。

    此代码包含丑陋、泄漏,不得在未经修改的情况下用于“生产”。
    #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;
    }

    唯一棘手的部分是:
    template <typename T, typename U>
    struct event_handler_impl : event_handler

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

    作为建议 - 考虑使用智能指针而不是原始指针。你也可以把函数 void subscribe_to_even(…)到处理程序基类,因此您可以删除第二个参数并将“this”传递给 event_handler_impl - new event_handler_impl<T, U>(this, handler_function)

    关于c++ - 将基类传递给接收父类(super class)的函数委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61172548/

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