Virtual method table

from Wikipedia, the free encyclopedia

The table of virtual methods ( English virtual method table or virtual function table , short VMT , VFT , vtbl or vtable ) is an approach of compilers of object-oriented programming languages to implement dynamic binding . Among other things, this is a prerequisite for inheritance and polymorphism . A table of virtual methods is a data structure that maps methods to concrete realizations (implementation of this method). Instead of addressing the implementations directly, they are addressed indirectly using the table.

Assignment of the tables of virtual methods (right) to the classes. Dachshund inherits from his dog ancestor

A table is assigned to each class , which assigns the address of the corresponding implementation to the virtual methods . In the languages Java , Smalltalk and Python these are all methods of a class, in C ++ , the .NET languages ​​and Object Pascal only those marked as "virtual". Every object has a hidden pointer to the table of the class according to which it was created.

The call to a non-virtual method is translated by the compiler by calling the implementation directly. This is determined based on the type of object assumed when the call was made. If a polymorphic object appears in the form of one of its ancestors, it has the ancestor's type and its implementation is therefore used.

If a virtual method is called instead, the compiler translates this into an indirect call to the implementation addressed in the table. This does not depend on the type of object assumed in the reference to the object, but rather on the original type of the object itself.

Implementation of the classes in C ++:

class Hund
{
private:
	string name_;
public:
	Hund (string name) : name_(name) {}
	virtual ~Hund() {};
	virtual void sitz() const =0;
	virtual void gibLaut() const {cout << "wuff" << endl;}
	virtual void getName() const {cout << name_ << endl;}
};

class Dackel: public Hund
{
public:
	Dackel (string name) : Hund(name) {}
	void sitz() const {cout << "platz" << endl;}
	void gibLaut() const {cout << "wau" << endl;}
};

Results in the following VFT, obtained with:

 g++ -fdump-class-hierarchy hund.cpp
 Vtable for Hund
 Hund::_ZTV4Hund: 7u entries
 0     (int (*)(...))0
 8     (int (*)(...))(& _ZTI4Hund)
 16    Hund::~Hund
 24    Hund::~Hund
 32    __cxa_pure_virtual
 40    Hund::gibLaut
 48    Hund::getName
 Vtable for Dackel
 Dackel::_ZTV6Dackel: 7u entries
 0     (int (*)(...))0
 8     (int (*)(...))(& _ZTI6Dackel)
 16    Dackel::~Dackel
 24    Dackel::~Dackel
 32    Dackel::sitz
 40    Dackel::gibLaut
 48    Hund::getName

This can then be used by writing functions or methods that are generally implemented for a dog.

void belle(const Hund &h)
{
	h.sitz();
	h.gibLaut();
}

However, a dachshund or any other breed of dog that may be added later can be handed over:

int main()
{
	Dackel d("Bello");
	belle (d);
	return 0;
}

The example is intended to show the concept: At the point of use, the specific form of an object should / must not be known at compile time. The object is known via the type of a base class. Calling a class function always leads to calling the function that belongs to the type of the actual instance.

Remarks

  1. virtual in C #, Overridable in VB.NET