Если нужно переопределить какой-либо метод базового класса в производном классе, то этот метод объявляется в базовом классе как виртуальный. Тогда программы выбирает версию метода, основываясь на типе объекта, а не на типе ссылки или указателя. Виртуальные функции очень полезны когда у вас есть указатель на массив из базовых объектов. Т.е. этот массив может содержать как базовые объекты так и дочерние, соответственно не будет же вызываться для дочернего объекта метод базового класса.
Так же существуют абстрактные классы, в которых без виртуальных функций никуда.
Все это очень хорошо расписано у
Праты в 13 главе.