Object-Oriented Programming

VTables

Michael L. Collard, Ph.D.

Department of Computer Science, The University of Akron

Dispatch

  • static dispatch

    selecting which implementation of an operation (method or function) to call at compile time

  • dynamic dispatch

    selecting which implementation of a polymorphic operation (method) to call at run time

The Compiler & Static Dispatch

  • The compiler uses static dispatch whenever it can:
    • free functions, non-virtual methods, static methods, method calls from non-pointer (or non-reference) variables
  • Why?
    • Less code to generate (program smaller)
    • Faster to call

Dynamic Dispatch

  • For method calls whose object is a pointer or reference variable
  • Requires more code than static dispatch
  • Slightly slower to call
  • Compilers have optimized dynamic dispatch, so speed disadvantage is smaller than it used to be

Original class Base Code

Problem Dynamic Dispatch Faces

  • Methods that it calls may not exist yet
  • The functions apply() are compiled so that for any class that inherits from the class Base, the function calls the proper method
  • Even though the parameter type at the time of compilation was a Base* or a Base&, the apply() functions must call the Base methods for Base objects, and the Derived methods for Derived objects

Add class Derived

How?

  • At compile time the virtual table or vtable is created to store the information required for the dynamic dispatch of virtual methods for a class
  • For every object of a class that has a vtable, the object has a pointer to the class vtable
  • Method calls go through the vtable for the class of an object

vtable for class Base

vtable for class Base with Added Methods

vtable for class Derived

Base vtable & functions

Derived vtable & functions

All Together Now

Base* to Base Object

Base* to Derived Object

Notes

  • Dependency of class Derived on class Base because changes to Base vtable (e.g., add or remove virtual methods) changes the layout of the class Derived vtable
  • Code compiled with the Base class (e.g., apply()) can only call class Base methods

A vtable has:

  • typeInfo
  • Array of pointers to virtual methods
  • Virtual methods calls for dynamic dispatch are stored in the program as an array index, i.e., [0] for vmethod1(), [1] for vmethod2(), [2] for vmethod3()

Conclusion

  • vtable mechanism supports polymorphism and virtual method calls, even when the derived class methods are not defined yet
  • Overhead of a pointer indirection
  • Overhead of preventing inlining
  • But, worth it in terms of code flexibility