First, calling a virtual function does not require a pointer or reference. As for the language, any call to a virtual function is a virtual call, unless you explicitly suppress the virtual sending mechanism using the name of the qualified function. For example, these
dD::call(); // calls `D::call()` directly dB::call(); // calls `B::call()` directly
- These are challenges that were clearly forced to be non-virtual. However this
d.call(); // calls `D::call()` virtually
- virtual call. In this case, it immediately becomes apparent to the compiler that the target function is D::call() , so the compiler usually optimizes this virtual call into a regular direct call. Conceptually, however, d.call() is still a virtual call.
Secondly, the call() made inside B::runB() is made using a pointer. The pointer is present there implicitly. The call() notation inside B::runB() is just a shorthand for (*this).call() . this is a pointer. Thus, the call is made using the pointer.
Thirdly, the key property of a virtual call is that the target function is selected in accordance with the dynamic type of the object used in the call. In your case, even if you are inside B::runB() , the dynamic type of *this object is D That is why it calls D::call() , as it should be.
Fourth, you really need a pointer or link to observe the actual polymorphism. Native polymorphism occurs when the static type of an expression of an object used in a call is different from its dynamic type. To do this, you really need a pointer or link. And this is exactly what you observe in this call (*this).call() inside B::runB() . Although the static *this type is B , its dynamic type is D , and the call is sent to D::call() .
AnT
source share