keywords: Virtual Functions, VTables

We all know what virtual functions are in C++, but how are they implemented at a deep level?

This is an array with pointers to functions, which are implementations of a particular virtual function. An index in this array represents particular index of a virtual function defined for a class. This includes pure virtual functions.

When a polymorphic class derives from another polymorphic class, we may have the following situations:

  • The deriving class does not add new virtual functions nor overrides any. In this case this class shares the vtable with the base class.
  • The deriving class adds and overrides virtual methods. In this case it gets its own vtable, where the added virtual functions have index starting past the last derived one.
  • Multiple polymorphic classes in the inheritance. In this case we have an index-shift between second and next bases and the index of it in the derived class
Can the vtable be modified or even directly accessed at runtime?

Not standard way - there’s no API to access them. Compilers may have some extensions or private APIs to access them, but that may be only an extension.

Does the vtable exist for all classes, or only those that have at least one virtual function?

Only those that have at least one virtual function (be it even destructor) or derive at least one class that has its vtable (“is polymorphic”).

Do abstract classes simply have a NULL for the function pointer of at least one entry?

That’s a possible implementation, but rather not practiced. Instead there is usually a function that prints something like “pure virtual function called” and does abort(). The call to that may occur if you try to call the abstract method in the constructor or destructor.

Does having a single virtual function slow down the whole class? Or only the call to the function that is virtual? And does the speed get affected if the virtual function is actually overwritten or not, or does this have no effect so long as it is virtual.

The slowdown is only dependent on whether the call is resolved as direct call or as a virtual call. And nothing else matters. :)

If you call a virtual function through a pointer or reference to an object, then it will be always implemented as virtual call - because the compiler can never know what kind of object will be assigned to this pointer in runtime, and whether it is of a class in which this method is overridden or not. Only in two cases the compiler can resolve the call to a virtual function as a direct call:

  • If you call the method through a value (a variable or result of a function that returns a value) - in this case the compiler has no doubts what the actual class of the object is, and can “hard-resolve” it at compile time.
  • If the virtual method is declared final in the class to which you have a pointer or reference through which you call it (only in C++11). In this case compiler knows that this method cannot undergo any further overriding and it can only be the method from this class.

Note though that virtual calls have only overhead of dereferencing two pointers. Using RTTI (although only available for polymorphic classes) is slower than calling virtual methods, should you find a case to implement the same thing two such ways. For example, defining virtual bool HasHoof() { return false; } and then override only as bool Horse::HasHoof() { return true; } would provide you with ability to call if (anim->HasHoof()) that will be faster than trying if(dynamic_cast<Horse*>(anim)). This is because dynamic_cast has to walk through the class hierarchy in some cases even recursively to see if there can be built the path from the actual pointer type and the desired class type. While the virtual call is always the same - dereferencing two pointers.

Origin:
https://stackoverflow.com/questions/99297/how-are-virtual-functions-and-vtable-implemented


It's enough for me to be sure that you and I exist at this moment. ― Gabriel García Márquez, One Hundred Years of Solitude