The problem
I'm trying to achieve polymorphism by having types of Event subtypes inherit from the base class Event. The idea is that there is always an active event, denoted by the pointer in Runner (Event* current_event). When the Runner::step method is called, the Event::go method is called, which flips some switches and changes the current behaviour of the program. Then, the pointer is pointed at a different event until Runner::step is called again.
The issue is that the pointer is always using the base class Event versions of variables. It might be a simple fix but I'd be greatful if somebody could point it out to me.
The code
#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;
};
This will output
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
Where I expect it to output:
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```