Virtual function

A virtual method in object-oriented programming, a method of a class whose entry point is determined at runtime. This so-called dynamic binding allows to derive classes from a base class and to overwrite or to overload functions. The concept of virtual methods implemented by a compiler (translator ), for example by means of virtual tables.

Programmer of the languages ​​C , SystemVerilog or Object Pascal have to explicitly deal with this issue and decide which methods they define "virtual" as. In other object -oriented languages ​​such as Java, Smalltalk and Python, all methods are automatically virtual.

Deriving classes and overriding methods

In object-oriented programming languages ​​such as C , C #, Pascal or Java object, it is possible to create classes by being derived from the other classes. Derived classes have all the methods and data fields of the original class, and can be extended with additional fields and methods. In some cases it is desirable to modify existing methods, that is to rewrite it. In this case one speaks of overwriting.

Through the derivation of classes, there is also the so-called polymorphism ( polymorphism ). Each class represents a distinct data type. Derived classes have at least one other type of data, namely that of the base class (also known as upper class or super class). Thus, it is for example possible to use a list of objects of the class A, although in reality objects of class B ( which was derived from A) are stored in the list.

Problem for the translator

A compiler (translator ) attempted during translation to specify for each function called an address in memory at which a function or method begins. Later in the program, the CPU will start with a call to the appropriate address and continue working ( besides some administrative work is still necessary that no further importance is here). In derived classes with overridden or overloaded methods, however, is not always at compile time ( compile time ) know which method to call. In the example with the list (see below ), the translator, for example, do not always know when other objects appear as objects of type A in the list.

Solution: Indirect Addressing

One solution is to indirect addressing via a table. Can not find the translator, which method should be started, an entry point is not specified, but stored only a reference to an entry in the virtual table. In it are the concrete entry points that should be skipped during program execution.

For example, a list of elements of type A and B. A is superclass of B and B overrides the method m from A. Well to be called for each element m the method. There is therefore a table of addresses of functions to each class. The addresses listed in the table of objects of type B are different from those of the table of objects of type A. In the machine code, the CPU will be instructed to call the function that is on the table position "m" of the current object.

Abstract virtual methods

Virtual methods can also additionally be abstract. In the class in which the method is declared, the method remains empty, but can theoretically be called yet. The abstract method is overridden only in a derived class, and can then be used.

If a class contains one or more abstract methods, it is called an abstract class. In C and Java, it is not possible to create an object of an abstract class. Object Pascal allows this, however, an exception is raised when calling an abstract method.

Pure virtual methods

Pure virtual methods ( pure virtual functions ) extend the concept of abstract method even further. Because an abstract, virtual method can theoretically be called yet, it is for example in C methods explicitly zero. Thus these methods can not be called and may differ from the class not an object to be created. Derived classes must implement these methods only, only an object can be generated from them.

Example:

# Include using namespace std;   class animal { public:      virtual void eat () = 0; / / Pure virtual method };   class Wolf: public Animal { public:      void eat () { cout << " Wolves can eat! " << Endl; } / / Implementation of the virtual method };   int main () {      Wolf wolf1;      wolf1.essen (); / / OK } Virtual destructors

Another peculiarity of C destructors are used for final tasks such as freeing memory. Each class whose attributes are not primitive types or other resources used (such as a database connection ), this should release necessarily in its destructor. To always access the correct destructor, the destructor of the ancestors must be declared as virtual.

The following example illustrates the use and inheritance of non-virtual destructors, which leads to undefined behavior.

# include   class A { public:      A ( ) {}      ~ A () { std :: cout << " Destroy A" << std :: endl; } };   class B: public A { public:      B () {}      ~ B () { std :: cout << " Destroy B " << std :: endl; } };   int main () {      A * b1 = new B;      B * b2 = new B;        delete b1; / / According to C standard undefined behavior                  / / Top A () is only called ~ because ~ A () not virtual      delete b2; / / Destructor ~ B () and ~ A ( ) can be called        return 0; } A possible output would be:

806178
de