我正在學習C++,並希望構建類似於C#事件的東西來處理嵌入式C++項目中的中斷。C++多態性:我錯過了什麼?
到目前爲止,我想出了一個幾乎可以實現我想要的解決方案。不過,我需要一些關於多態性(?)的幫助。下面的代碼片段是一種最小的例子重現我的情況:
#include <iostream>
struct Event
{ };
struct EventHandler
{
virtual void Esr (const Event& I) { }
};
struct EventSender
{
EventSender (EventHandler& Handler) : _Handler (Handler) { }
template <typename T>
void SendEvent (const T&) const
{
_Handler.Esr (T());
}
EventHandler& _Handler;
};
struct SpecialEvent : public Event
{ };
struct MyHandler : public EventHandler
{
void Esr (const Event& I) override { std::cout << "Event" << std::endl; }
void Esr (const SpecialEvent& I) { std::cout << "SpecialEvent" << std::endl; }
};
int main()
{
MyHandler handler;
EventSender sender (handler);
/* Invoke directly */
handler.Esr (Event());
handler.Esr (SpecialEvent());
/* Invoke indirectly */
sender.SendEvent (Event());
sender.SendEvent (SpecialEvent()); // Expected cout msg: "SpecialEvent"
return 0;
}
預期的控制檯輸出:
Event
SpecialEvent
Event
SpecialEvent
實際控制檯輸出:
Event
SpecialEvent
Event
Event
什麼編譯器/連接器在這裏,我不知道?
不知道這是有關這個問題,但爲什麼你傳遞事件實例'SendEvent'和那麼在'SendEvent'裏面忽略這個參數,但是一個新的'Event'實例被傳遞給'Esr'? – user463035818
解決這些問題的正確工具是您的調試器。在*堆棧溢出問題之前,您應該逐行執行您的代碼。如需更多幫助,請閱讀[如何調試小程序(由Eric Lippert撰寫)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。至少,您應該\編輯您的問題,以包含一個[最小,完整和可驗證](http://stackoverflow.com/help/mcve)示例,該示例再現了您的問題,以及您在調試器。 –
一個有趣的問題:向答案邁進一步,但不是一個完整的答案,因此是一個評論:通過替換{} is = 0使Esr方法變爲純虛擬。在方法聲明中。 –