Now, if we stop to think about it, functions defined as part of the parent class can never access data fields defined as part of the child class. Thus, if we can ensure that the only member functions ever executed will be those from the parent class, then the slicing away of the childs data fields will not be noticed.
This, ultimately, is why the rules for member function invocation in C++ are rather more complex than are the similar rules in other languages.
Because of slicing, with variables that are declared normally, the binding of function name to function body is based on the static (that is declared) type of the variable. This is true regardless whether the member function is declared virtual or not. C++ people say that such a value is simply not polymorphic, and they are right.
When variables are declared as pointers or references, they can be polymorphic, as slicing need not occur in this case. Therefore, the binding of a method name to the method body will be based either on the dynamic type, if the function is declared as virtual, or on the static type if not.