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