"... выбирается для разрешения вызова функции в последней строке путем перевода указателя this объекта в базовый класс ..." .О чем ты говоришь?Во всех ваших вызовах тип указателя объекта - Bbase *
, а функции, которые разрешают вызовы, принадлежат либо Bbase
, либо его потомкам.Компилятор никогда не выполняет обновление, чтобы разрешить ваши звонки.Фактически, для первых двух вызовов требуется downcasting для вызова правильной переопределения, так как переопределение принадлежит классу, расположенному ниже в иерархии.Что касается двух последних вызовов - они отправляются в класс Bbase
через указатель типа Bbase *
.Типы точно совпадают, приведения типов не происходит.
Что касается разрешения перегрузки ... Разрешение перегрузки - это процесс времени компиляции, который основан на статических типах аргументов и рангах возможныхпреобразования.Вы указали аргумент типа A2 *
.Кандидат f(A2 *)
соответствует вашему аргументу точно .Кандидат f(A1 *)
требует дополнительного преобразования с A2 *
на A1 *
.Кандидат, который точно соответствует, считается лучшим, поэтому он выигрывает разрешение перегрузки.Простой.