Используете ли вы спецификатор virtual при перекрытии функции:
class B {
virtual void f();
};
class D : public B {
virtual void f(); // <- здесь
};
Если последовательно использовать virtual в этом случае, то с первого взгляда, не просматривая базовые классы можно отличить виртуальные функции от невиртуальных; но не так удобно отличать первое объявление виртуальной функции от объявлений перекрывающих его. Если не использовать virtual, то наоборот. Поэтому с точки зрения самодокументирования программы счет 1:1.
А вот если функции B::f и D::f по ошибке получают разные имена, ошибку эту можно скорее заметить, если virtual при перекрытии не используется; потому-что функция в производном классе перестает быть виртуальной, и если в программе имеется производный от D класс E, ошибка будет проявляться и в случаях, когда объекты класса E используются как объекты класса D, а не только когда объекты класса D используются как объекты класса B.
То есть мое предварительное мнение таково, что использовать спецификатор virtual при перекрытии функции не нужно. Тем более без него короче.