Это зависит от предполагаемой семантики A, B и C и семантики сравнения (). Сравнение - это абстрактное понятие, которое не обязательно имеет единственное правильное значение (или вообще какое-либо значение). На этот вопрос нет однозначного правильного ответа.
Вот два сценария, где сравнение означает две совершенно разные вещи с одинаковой иерархией классов:
class Object
{
virtual int compare(const Object& ) = 0;
float volume;
};
class Animal : Object
{
virtual int compare(const Object& );
float age;
};
class Zebra : Animal
{
int compare(const Object& );
};
Мы можем рассмотреть (как минимум) два способа сравнения двух зебр: какая старше и какая больше? Оба сравнения корректны и легко вычислимы; Разница в том, что мы можем использовать объем, чтобы сравнить Зебру с любым другим Объектом, но мы можем использовать только возраст, чтобы сравнить Зебр с другими Животными. Если мы хотим, чтобы compare () реализовала семантику сравнения возраста, не имеет смысла определять compare () в классе Object, так как семантика не определена на этом уровне иерархии. Стоит отметить, что ни один из этих сценариев не требует какого-либо приведения, так как семантика определяется на уровне базового класса (будь то Object при сравнении объема или Animal при сравнении возраста).
Это поднимает более важную проблему - некоторые классы не подходят для одной функции catch (all) all compare (). Часто имеет смысл реализовывать несколько функций, которые явно указывают на то, что сравнивается, например, Compare_age () и Compare_volume (). Определение этих функций может происходить в той точке иерархии наследования, где семантика становится актуальной, и адаптировать их к дочерним классам должно быть тривиально (если вообще требуется адаптация). Простое сравнение с использованием Compare () или оператора == () часто имеет смысл только с простыми классами, где правильная семантическая реализация очевидна и однозначна.
Короче говоря ... "это зависит".