why does the following code changes its output when I replace virtual void f() in class A with void f()? (it prints B when void, C when virtual void)
When a class inherits from another (like in your case B and C from A and B respectively), the virtual keyword means that the method it is applied to (f()) in your case) can be re-defined for child classes. In your case, it allows classes B and C to have their own personal implementations for f(), through polymorphism. Notice how in your main() you create a C object, and not a B:
B *p = new C;
it seems confusing because the address of that C object is stored in a B pointer, but is is legal in C++ because a C object is in fact B object, because it inherits (has a "is a" relationship) from B. When you call f()on that B pointer storing a C object, polymorphism is enabled because the method is virtual: it selects the C-version of the f() method, and that is why you see a C printed.
When you remove the virtual polymorphism is disabled the the C object is seen as a B object, and the B-version of f() is selected. Then you see "B" on your screen.
Why does the following code print more than "CPP!"?
From this, it says that:
The switch statement has a somewhat peculiar syntax inherited from the
early times of the first C compilers, because it uses labels instead
of blocks. In the most typical use (shown above), this means that
break statements are needed after each group of statements for a
particular label. If break is not included, all statements following
the case (including those under any other labels) are also executed,
until the end of the switch block or a jump statement (such as break)
is reached.
So, try this instead:
int main ()
{
int x[10] = {1,2,3,4,5,6,7,8,9,10};
for(int y:x)
{
switch(y)
{
case 1:cout<<"C";break; // <- notice the 'break'!
case 3:cout<<"P";break;
case 7:cout<<"P";break;
case 8:cout<<"!";break;
}
}
}