The idea that I want to convey here is that the only time you need to look at
the dynamic type of a pointer/reference to an object is when you are invoking
a virtual function (or the destructors are virtual). And here we are not
dealing with any virtual functions, so we only need to look at static types of
pointers/references.
(1) int i = xptr->Xpublic;
This is clearly legal as xptr has static type of X* and X has a public
data member Xpublic.
(2) int j = xptr->Ypublic;
This is not legal (even though xptr points to an object of type Y) because
you dont have to look at the dymanic type of xptr (which is Y*), you just
have to look at the static type (which is X*). And X does not have any
data member Ypublic. So,this is not allowed.