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

c++, polymorphism

Solution

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.

Problem

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().

Original source