Invocation
A call to d->f1
is handled by dereferencing d
's D::B1
vpointer, looking up the f1
entry in the vtable, and then dereferencing that pointer to call the code.
In the case of single inheritance (or in a language with only single inheritance), if the vpointer is always the first element in d
(as it is with many compilers), this reduces to the following pseudo-C++:
Where *d refers to the virtual method table of D and refers to the first method in the vtable. The parameter d becomes the "this" pointer to the object.
In the more general case, calling B1::f1
or D::f2
is more complicated:
The call to d->f1 passes a B1 pointer as a parameter. The call to d->f2 passes a B2 pointer as a parameter. This second call requires a fixup to produce the correct pointer. It is impossible to call B2::f2 since it has been overridden in D's implementation. The location of B2::f2 is not in the vtable for D.
By comparison, a call to d->f0
is much simpler:
Read more about this topic: Virtual Method Table