And how is the compiler supposed to determine the (possibly dynamic) type of an object at compile time, in order to determine when to make the call statically?
If you declare a method virtual, you're telling the compiler to use late binding. If you don't, you're telling the compiler to use early binding. You always know what you're going to get. That's why the keyword is there -- so you don't have to guess.
"Can anyone cite an example of where you'd actually want to call different methods depending on whether you're using a base or a derived pointer?"
Not sure what you're asking here. Are you talking about the ability to hide a base class method with a derived class method? It's not really considered a good idea to do such a thing (see: http://www.parashift.com/c++-faq-lite/strange-inheritance.ht...), but it's an inevitable consequence of mixing early- and late-binding features in the same language.