The virtual table is created when the class objects are constructed. When you construct a Derived
object, it will first call the Base
constructor (which creates the vtable and writes its own Base::fun1
into that. Then the Derived
constructor runs and overwrites the vtable entry for fun1
with its own implementation (Derived::fun1
).
If you then, at any later point (even from within any Base
function) call fun1
of such an object instance, it will look into the vtable and call whatever function it finds there. As explained above, it is Derived::fun1
that is in the vtable of a Derived
object after construction, so this is the one that will get called. It doesn't matter that you are currently in a Base
function, the vtable entry does not change.
Note that during construction, the vtable is not fully set up: If you were to call fun1
from within the Base
constructor, you would not call Derived::fun1
but Base::fun1
because Derived
did not replace the vtable entries yet.
Also note that fully specifying the function (e.g. calling Base::fun1()
on a Derived
instance) will not do a vtable lookup but instead use exactly the specified function.