X::X()
Y::Y()
X::~X()
The destructor for Y was never invoked and hence the memory allocated for Y::y
was never released. So, we have a memory leak. Since xptr was pointing to an
object of class Y, what we would liked the destructor for Y to be invoked. In
other words, which destructor is invoked should have been determined not by
the static type of xptr (which happens to be 'pointer to X' in this case), but
by its dynamic type ('pointer to Y'). So, once again the keyword virtual comes to the rescue
See how adding the keyword virtual does the trick