Virtual Method Table - Invocation

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++:

(*((*d)))(d)

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:

(*(*(d/*pointer to virtual method table of D (for B1)*/)))(d) /* Call d->f1 */ (*(*(d/*pointer to virtual method table of D (for B2)*/)))(d+8) /* Call d->f2 */

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:

(*B1::f0)(d)

Read more about this topic:  Virtual Method Table