Object-Oriented Programming

Dispatch

Michael L. Collard, Ph.D.

Department of Computer Science, The University of Akron

Dispatch

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

  • static dispatch
  • dynamic dispatch

Static Dispatch

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

  • Which operation (method or function) will be called is determined at compile time
  • Fast as a call can be made
  • Preferred by the compiler for these reasons

C++ Static Dispatch

  • The compiler uses static dispatch whenever it can:
    • free functions
    • non-virtual methods
    • static methods
    • method calls from non-pointer and non-reference variables
  • Why? Less code to generate (program smaller)
  • Why? 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 the 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

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

vtable for class Base with Added Methods

vtable for class Derived

Base vtable & functions

Derived vtable & functions

Combined

Base* to Base Object

Base* to Derived Object

Combined

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

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