There are two steps involved: overload selection (X(B&)
vs. X(D&)
) and, once that is done, finding the right implementation of the selected function. The former happens at compile time and depends on the static types of the object and its arguments, the latter happens at run-time and depends on the dynamic type of the object (note it does not depend on the dynamic type of the arguments).
The four objects are declared as follows: d1
and d2
are D&
, so their static type is D&
, and b1
and b2
are declared as B&
, so their static type is B&
. The static type is what you've declared in the code.
But the dynamic type for all four is D
, because all four references actually refer to objects that you've created as D
-objects in main()
.
Therefore, first step, overload selection: In the case of b1.X(b2)
and b1.X(d2)
, there is only one possible overload, X(B&)
, because the static type is B&
, and the class definition for B
has only this one function. But in the case of d1.X(b2)
and d1.X(d2)
, the overload selection is based on the class definition of D
, because the static type is D&
. So two overloads are considered: X(B&)
and X(D&)
. When the argument is b2
, the former overload is chosen, and when the argument is d2
, the latter overload is chosen – all based on the static (=declared) types of object and arguments.
Second step, chosing the right implementation of the selected overload. This happens at run-time and depends on the dynamic type of the object (not the arguments). So in the case of b1.X(b2)
, because the dynamic type of b1
is D
, it will end up calling D::X(B&)
. Same for b1.X(d2)
: The overload selected in the previous step was X(B&)
, but the implementation chosen is D::X(B&)
. (D::X(D&)
is no candidate at this point, because that would be a different overload, and the overload has been chosen based on the static type already). In the case of d1.X(b2)
and d1.X(d2)
, the selected functions are the same as in the first step, D::X(B&)
and D::X(D&)
, because the dynamic type of the object is the same as the static type.