由于签名不同,调用了错误的 child class 函数

Wrong child class function being called due to signature difference

我有一个发射事件的事件发射器和处理事件的事件处理程序。我可以扩展 Event object 来制作不同的事件,例如 AlarmEvent,并扩展 EventHandler object 来制作 AlarmEventHandlerEventHandler 有一个函数 HandleEvent(Event &event)。这会导致 child class 可能有 HandleEvent(AlarmEvent &event) 方法的问题。显然,这是两个不同的功能,因此这里没有发生重写。我需要 HandleEvent 被 child class.

覆盖

我完全理解问题是每个 EventHandler 都有不同的 HandleEvent 签名,所以 EventEmitter 将始终处理基数 EventHandler::HandleEvent 的事件。我想通过使用 Event &event 作为 EventEmitter::Emit 的参数,它会知道它正在处理哪种 Event 并选择正确的方法。

如何让我的 EventEmitter 调用 AlarmEventHandler::HandleEvent 而不是基本方法 EventHandler::HandleEvent

// Example program
#include <iostream>
#include <string>
#include <vector>

// event types
class Event {};
class AlarmEvent : public Event {};

// event handler
class EventHandler {
    public:
        virtual void HandleEvent(Event event);
};
void EventHandler::HandleEvent(Event event){
    std::cout << "Handle event " << std::endl;   
}

// alarm event handler
class AlarmEventHandler : public EventHandler {
    public:
        void HandleEvent(AlarmEvent event);  
};
void AlarmEventHandler::HandleEvent(AlarmEvent event){
    std::cout << "Handle alarm event " << std::endl;   
}

// event emitter
class Emitter {
    public:  
        std::vector<EventHandler*> handlers;
        void Emit(Event &event);
};
void Emitter::Emit(Event &event){
    for(size_t i = 0; i < this->handlers.size(); i++){
        this->handlers[i]->HandleEvent(event);   
    }
}

int main()
{
    AlarmEventHandler handler;
    AlarmEvent event;
    Emitter emitter;
    emitter.handlers.push_back(&handler);
    // problem:
    // Handle event printed instead of Handle alarm event
    emitter.Emit(event);
}

使用 dynamic_cast!

所以你的 AlarmEventHandler 可能看起来像:

// alarm event handler
class AlarmEventHandler : public EventHandler {
    public:
        void HandleEvent(const Event &event); // Our polymorphic override
        void HandleEvent(AlarmEvent event);  // Our custom Alarm logic
};

void AlarmEventHandler::HandleEvent(const Event &event){
    try {
        HandleEvent(dynamic_cast<const AlarmEvent&>(event));
    } catch(const std::exception& e) {
        std::cerr << "I can't handle things that aren't AlarmEvents!" << std::endl;
    }
}

void AlarmEventHandler::HandleEvent(const AlarmEvent &event){
    std::cout << "Handle alarm event " << std::endl;   
}

不过,要做到这一点,您需要 Event 成为多态 class。所以你使析构函数 virtual:

class Event { 
    public: virtual ~Event() {} //Need this so Event is a polymorphic class
};

在此处查看 运行:https://ideone.com/KMkLfq

您没有覆盖 HandleEvent(),您正在重载它。

您需要一个指针或引用才能利用动态分派而不必强制转换。

内嵌评论:

#include <iostream>
#include <string>
#include <vector>

// event types
class Event {
    public:
        virtual ~Event();                       // make base destructor virtual
};

Event::~Event() {}

class AlarmEvent : public Event {};

// event handler
class EventHandler {
    public:
        virtual void HandleEvent(Event& event);
        virtual ~EventHandler();                 // virtual base destructor
};

EventHandler::~EventHandler() {}

void EventHandler::HandleEvent(Event& event){
    std::cout << "Handle event " << std::endl;   
}

// alarm event handler
class AlarmEventHandler : public EventHandler {
    public:
        //void HandleEvent(AlarmEvent& event);  // overload, does not override
        void HandleEvent(Event& event);
};

void AlarmEventHandler::HandleEvent(Event& event){
    std::cout << "Handle alarm event " << std::endl;   
}

// event emitter
class Emitter {
    public:
        Emitter() : handlers() {}
        std::vector<EventHandler*> handlers;
        void Emit(Event &event);
};

void Emitter::Emit(Event& event) {
    for(size_t i = 0; i < this->handlers.size(); i++){
        this->handlers[i]->HandleEvent(event);   
    }
}

int main() {
    AlarmEventHandler handler;
    AlarmEvent event;
    Emitter emitter;
    emitter.handlers.push_back(&handler);
    emitter.Emit(event);
}

编译为

g++ -std=c++98 -O3 -Wall -Wextra -Weffc++ -pedantic -pedantic-errors

输出:

Handle alarm event