Существует два этапа: выбор перегрузки (X(B&)
против X(D&)
) и, как только это будет сделано, найти правильную реализацию выбранной функции. Первое происходит во время компиляции и зависят от статических типов объекта и аргументов, последний происходят во время выполнения и зависит от динамического типа объекта (обратите внимание, что делает не зависит от динамический тип аргументов).
Четыре объекты объявляются следующим образом: d1
и d2
являются D&
, поэтому их статического типа является D&
и b1
и b2
объявлены как B&
, так что их статический тип B&
. Статический тип - это то, что вы указали в коде.
Но динамический тип для всех четырех является D
, потому что все четыре ссылки фактически относится к объектам, которые вы создали, как D
-Объектов в main()
.
Таким образом, первый шаг, выбор перегрузки: В случае b1.X(b2)
и b1.X(d2)
, есть только один возможный перегрузки, X(B&)
, так как статический тип B&
, а определение класса B
имеет только эту одну функцию. Но в случае d1.X(b2)
и d1.X(d2)
выбор перегрузки основан на определении класса D
, поскольку статический тип - D&
. Так считаются две перегрузки: X(B&)
и X(D&)
. Когда аргумент равен b2
, выбирается первая перегрузка, а когда аргумент равен d2
, последняя перегрузка выбирается – на основе статических (= объявленных) типов объектов и аргументов.
Второй шаг, выбрав правильную реализацию выбранной перегрузки. Это происходит во время выполнения и зависит от динамического типа объекта (а не от аргументов). Поэтому в случае b1.X(b2)
, поскольку динамический тип b1
равен D
, он в конечном итоге вызовет D::X(B&)
. То же самое для b1.X(d2)
: Перегрузка, выбранная на предыдущем шаге, была X(B&)
, но выбрана реализация D::X(B&)
. (D::X(D&)
на данный момент не является кандидатом, потому что это будет другая перегрузка, и перегрузка была выбрана на основе статического типа уже). В случае d1.X(b2)
и d1.X(d2)
выбранные функции такие же, как на первом этапе, D::X(B&)
и D::X(D&)
, поскольку динамический тип объекта совпадает с типом статического типа.
Полиморфизм происходит только с указателями и ссылками; проходящий по значению срезов '' '' '' '' '' '' '' '' '' ''. Также даже если вы исправите это, перегрузка 'D :: X (D)' не будет видна при вызове 'X' через' B & '. –
@SethCarnegie Я исправил свое сообщение, чтобы включить ссылки. По-видимому, b1.X (b2) вызовет DX (B & b) ..... это то, что я не понимаю ... – user997112
'B' не имеет функции' X (D) ', только' D' делает. Также типы аргументов для функций (виртуальные или статические, либо) принимаются статически, а не динамически. –