This is due to slicing . Run-time polymorphism only works with a pointer or reference in C ++. You can get a virtual dispatch with another variable:
B b;
A& a = b;
cout << a.f() << endl;
Or you can directly assign a pointer, for example here:
A* aptr = new B;
aptr->f();
delete aptr;
B . , . GCC -Wnon-virtual-dtor .