Проблема
Я пытаюсь достичь полиморфизма, используя типы подтипов Event, наследуемых от базового класса Event
. Идея состоит в том, что всегда есть активное событие, обозначаемое указателем в Runner (Event* current_event
). Когда вызывается метод Runner::step
, вызывается метод Event::go
, который переключает некоторые переключатели и изменяет текущее поведение программы. Затем указатель указывает на другое событие, пока Runner::step
не будет вызван снова.
Проблема в том, что указатель всегда использует базовый класс Event
версий переменных. Это может быть простым исправлением, но я был бы рад, если бы кто-то мог указать мне на это.
Код
#include <iostream>
using namespace std;
struct Flags {
public:
bool withCheese = false;
bool withBiscuits = false;
};
class Event {
std::string description = "The base class";
public:
std::string id = "Base";
Event() = default;
~Event() = default;
Event(Event const &event) = default;
Event &operator=(Event &&) = default;
virtual void go(Flags &flags) {};
virtual void printDescription() {
std::cout << description << std::endl;
}
};
class EatCheese : public Event {
std::string description = "We eat cheese now";
public:
using Event::Event;
std::string id = "EatCheese";
void go(Flags &flags) override {
flags.withCheese = true;
flags.withBiscuits = false;
};
};
class EatBiscuits : public Event {
std::string description = "We eat biscuits now";
public:
using Event::Event;
std::string id = "EatBiscuits";
void go(Flags &flags) override {
flags.withCheese = false;
flags.withBiscuits = true;
};
};
class Runner {
public:
EatCheese eventA;
EatBiscuits eventB;
Event *current_event = &eventA; // The problematic line: this still points to Base, not eventA.
Flags flags;
Event* step() {
cout << "description: ";
current_event->printDescription();
current_event->go(flags);
if (current_event->id == "EatCheese") {
cout << "We have EatCheese"<<endl;
current_event = &eventB;
}
else if (current_event->id == "EatBiscuits") {
cout << "We have EatBiscuits"<<endl;
current_event = &eventA;
}
cout << endl;
return current_event;
}
};
int main() {
Runner runner;
cout << "current_event_id: " << runner.current_event->id << ", with biscuits: " << runner.flags.withBiscuits << ", with Cheese: " << runner.flags.withCheese << endl;
runner.step();
cout << "current_event_id: " << runner.current_event->id<< ", with biscuits: " << runner.flags.withBiscuits << ", with Cheese: " << runner.flags.withCheese << endl;
runner.step();
cout << "current_event_id: " << runner.current_event->id<< ", with biscuits: " << runner.flags.withBiscuits << ", with Cheese: " << runner.flags.withCheese << endl;
return 0;
};
Это выведет
current_event_id: Base, with biscuits: 0, with Cheese: 0
description: The base class
current_event_id: Base, with biscuits: 0, with Cheese: 1
description: The base class
current_event_id: Base, with biscuits: 0, with Cheese: 1
Где я ожидаю, что это выведет:
current_event_id: EatCheese, with biscuits: 0, with Cheese: 1
description: We eat cheese now
current_event_id: EatBiscuits, with biscuits: 1, with Cheese: 0
description: We eat biscuits now
current_event_id: EatCheese, with biscuits: 1, with Cheese: 0```