Ваша проблема основана на том факте, что хотя generateEvent
действительно создает KeyEvent
, это то, что знает только программист (вы). Что знает компилятор , так это то, что generateEvent
возвращает Event
, что в общем случае , а не на самом деле KeyEvent
. Поэтому компилятор жалуется, что вы рассматриваете что-то, что формально (как говорится в определении функции) не является KeyEvent
как KeyEvent
.
Скорее всего, то, что вы хотите сделать внутри main
, - это выполнить какое-то действие, если событие на самом деле KeyEvent
. Это распространенный сценарий, и нет ничего плохого в том, что вы пытаетесь сделать. Вам просто нужно сделать это по-другому.
В этом случае мы хотим «выполнить действие X» над событием, где «действие X» - это нечто иное, в зависимости от того, является ли событие KeyEvent
или чем-то еще. Это можно сделать с помощью виртуальных функций, например:
class Event
{
public:
string type;
string source;
virtual void PerformActionX();
};
А потом:
int main()
{
Event e = generateEvent();
e.PerformActionX();
return 0;
}
Реализация PerformActionX
будет отличаться для каждого производного класса. Метод также может быть чисто виртуальным или нет. Все это зависит от того, что именно вы хотели бы сделать.
В качестве заключительного замечания есть сценарии (и некоторые ответы на этот вопрос), в которых предлагается попытаться «выяснить», какой именно тип события e
, а затем привести к этому типу и выполнить какое-то явное действие (например, доступ к key
члену KeyEvent
), если это определенный тип. Такая обработка называется переключателем типа , и это, как правило, плохая идея. Хотя могут существовать допустимые сценарии, когда требуется переключение типов, гораздо лучше обрабатывать такие случаи так, как они предназначены для обработки на объектно-ориентированном языке (с виртуальными функциями). Сначала научитесь делать вещи по правилам, а потом нарушайте правила.