After encountering a similar situation in a real-world application I decided to put together a demo which shows that if I store derived classes as a pointer to the base class, and call a virtual method the behavior of the derived class will be incorrect. See the code below:
struct IntWrapper { int value; };
struct Base {
virtual ~Base() = default;
virtual void myMethod() = 0;
};
struct Foo : public Base {
const IntWrapper& x;
Foo(const IntWrapper& x) : x(x) {}
void myMethod() override {
std::cout << std::to_string(x.value) << std::endl;
}
};
struct Bar : public Base {
const IntWrapper& x;
const IntWrapper& y;
Bar(const IntWrapper& x, const IntWrapper& y) : x(x), y(y) {}
void myMethod() override {
std::cout << std::to_string(x.value) << " " << std::to_string(y.value) << std::endl;
}
};
int main()
{
Base* foo = new Foo(IntWrapper{3});
Base* bar = new Bar(IntWrapper{5}, IntWrapper{42});
foo->myMethod();
bar->myMethod();
return 0;
}
The expected output would be:
3
5 42
Instead I receive:
42
5 42
Interestingly, if I replace IntWrapper reference with a primitive int in the classes Foo and Bar the printed values will be correct. Can somebody explain to me why this behavior happens?