I am learning C++ inheritance, so I tried this code by creating a Base class dynamically and made a downcast to its Derived class (obviously its not valid to downcast) in order
What you are seeing is Undefined Behavior at work.
Your functions are non-virtual, they are simply member functions of the type you've told the compiler the pointer points to.
child *c = (child*)new parent;
This is a c-style cast that strong-arms the compiler into the belief that the pointer c definitely points to something that is a child.
Thus, when you call c->who()
, you are specifically calling child::who
, because the pointer is a pointer-to-child.
The reason nothing terrible happens and you see "I am child" is because you don't try to dereference that pointer or make use of any of the child-specific fields that your pointed-to-instance doesn't actually have. So you get away with it.