Q:

c++ polymorphism ((X*)y)->foo() vs ((X)*y).foo()

Suppose Y is a derived class from class X and X declares foo to be virtual. Suppose y is of type (Y*). Then ((X*)y)->foo() will execute the Y version of foo(), but ((X)*y).foo() will execute the X version. Can you tell me why polymorphism does not apply in the dereferenced case? I would expect either syntax would yield the Y version of foo().

A:

You are slicing the Y object part and copy the object into an X object. The function then called is called on an X object, and thus the function of X is called. 
When you specify a type in C++ in a declaration or cast, that is meant to say that the object declared or casted-to is actually of that type, not of a derived type. 
If you want to merely treat the object is being of type X (that is to say, if you want the static type of the expression be X, but still want it to denote an Y object) then you cast to a reference type
((X&)*y).foo()

This will call the function in the Y object, and will not slice nor copy into an X object. In steps, this does

Dereference the pointer y, which is of type Y*. Dereferencing yields an lvalue expression of type Y. An lvalue expression can actually denote an object of a derived type, even if its static type is the one of its base. 
Cast to a X&, which is a reference to X. That will yield an lvalue expression of type X. 
Call the function. 

Your original cast did

Dereference the pointer y. 
The resulting expression casted to X. This will yield to a copy operation into a new X object. The resulting expression of that is an rvalue expression of static type X. The dynamic type of the object denoted is also X, as is with all rvalue expressions. 
Call the function. 

A:

A cast always(*) creates a new object of the type you're casting to, which is constructed using the object you're casting.
Casting to X* creates a new pointer (that is, an object of type X*). It has the same value as y, so it still points to the same object, of type Y.
Casting to X creates a new X. It is constructed using *y, but it otherwise has nothing to do with the old object. In your example, foo() is called on this new "temporary" object, not on the object pointed to by y.
You are correct that dynamic polymorphism only applies to pointers and references, not to objects, and this is the reason why: if you have a pointer-to-X then the thing it points to might be a subclass of X. But if you have an X, then it's an X, and nothing else. virtual calls would be pointless.
(*) unless optimisation allows the omission of code that doesn't change the result. But optimisation isn't allowed to change what foo() function is called.

