Disregarding aspects of binding, it's not actually the compiler that determines this.
It is the C++ runtime that evaluates, via vtables and vpointers, what the derived object actually is at runtime.
I highly recommend Scott Meyer's book Effective C++ for good descriptions on how this is done.
Even covers how default parameters in a method in a derived class are ignored and any default parameters in a base class are still taken! That's binding.