Основное отличие виртуальной функции от обычной заключается в том, что для обычной функции связывание вызова функции с её определением осуществляется на этапе компиляции, а для виртуальных функций это происходит во время выполнения программы. 1
Виртуальная функция — это функция, которая определяется в базовом классе, а любой порождённый класс может её переопределить. 1 При вызове функции объектом этого класса-наследника будет вызвана именно эта переопределённая функция (если она не переопределена, то вызывается функция базового класса). 2
Функция, не объявленная как виртуальная, не может быть переопределена в классе-наследнике. 2 Даже если её там переопределить, при вызове всё равно будет вызываться функция базового класса. 2