If the base class is Base
, and a derived class is Der
, you can have a Base *p
pointer which actually points to an instance of Der
. When you call p->foo();
, if foo
is not virtual, then Base
's version of it executes, ignoring the fact that p
actually points to a Der
. If foo is virtual, p->foo()
executes the "leafmost" override of foo
, fully taking into account the actual class of the pointed-to item. So the difference between virtual and non-virtual is actually pretty crucial: the former allows runtime polymorphism, the core concept of OO programming, while the latter does not.