The concept of a virtual function is found in virtually every object-oriented programming language. Only methods on an object can be virtual, free-floating functions cannot.

In older, compiled languages such as C++ or Delphi that have significant pre-OO baggage, it is usually the case that only functions that are explictily declared as virtual are such, and the rest are not.

In more dynamic languages, interpreted languages, OO from the ground up languages and scripting languages, it is more often the case that all functions are virtual, as function dispatch happens at runtime anyway. Examples here are the object-oriented languages smalltalk and Python. When object-oriented code is done in PERL or PHP, this model is also used.

In Java, for instance, all member functions are assumed to be virtual unless they are explicitly declared to be final.

As Ariels points out, with languages where all methods are virtual, the term is not much used except in explaining the language to novices. In everyday use of these languages, virtual functions are just the way things are.

The use of the virtual function is to enable polymorphism.

I would define a virtual function like this:
If a method on an object is called, then even if the caller has a variable typed as a base class type and no knowledge of which subclass they are dealing with, when the method is called the correct subclassed method (the override) is invoked.

Confusing? Let's do an example.
I have a class called Vehicle. It has a method called Drive. Of course, you cannot drive a generic vehicle, and all that the method body does is report an error that the method must be overridden in a subclass. It could also be a pure virtual method, also called an abstract method, meaning that it has no implementation and must be overridden by a subclass.

Naturally, I make two subclasses of Vehicle, say Bicycle and Truck. Both of these implement the Drive method, albeit by doing very different things.

Now if I have a piece of code that has a Vehicle object (which must be actually either a Bicycle or a Truck, but I have it typed as a Vehicle). This is standard OO programming, as the base class defines an interface contract which the subclasses must honour.

I call the Drive method, what happens? If the Drive method is not virtual, I get the error message as the Drive method on the Vehicle class is called, as the calling code only knows that it has a Vehicle. That's not what is wanted.

But if Drive is a virtual method, then the correct method will be called, even though the caller may be unaware of the exact type that they are dealing with.

To go further, this code that works with a Vehicle object need not be changed if I later write a third subclass of Vehicle, say Segway and ask the code to act upon this vehicle.

Virtual methods are implemented, as most things are, by introducting a layer of indirection.

In the case of compiled languages the indirection takes the form of a virtual method table between the caller and the method called. Each object has a table of virtual methods, and the caller looks up the address to call in this table. This is sometimes called runtime dispatch or dynamic binding.

The overhead for using this table is typically only a few machine instructions, and is thus in almost all cases a price well worth paying for the flexibility and extensibility.

A virtual function (more properly, a virtual method, although that terminology is almost never used) is a member function called with dynamic binding. Some languages (e.g. Smalltalk) offer only dynamic binding, and so don't use the term. It's chiefly found by people talking about C++ and related languages, where both static binding and dynamic binding co-exist.

Normally, C++ provides static binding: the compiler figures out (at compile time) which method should be called. For example, say we have code

class Shape {
public:
  void draw() const;  // slow drawing routine
  void move(int sx, sy) {
    cx += sx;
    cy += sy;
  }
  // ...
private:
  int cx, cy;         // coordinates of centre
};

class Triangle : public Shape {
public:
  void draw() const;  // fast specialised drawing routine
  // ...
};

class Square : public Shape {
public:
  void draw() const;  // fast specialised drawing routine
  // ...
};
The intent is that a Shape is abstract: while it makes sense to move (translate) it, it cannot be drawn without knowing some more about it.

The C++ compiler will resolve all method calls for Shapes at compile time, giving the following behaviour:

void f(Square& s, Triangle *t)
{
  s.move(100,100);              // (1) call Shape::move
  t->move(-50,-50);             // (2) call Shape::move
  s.draw();                     // (3) call Square::draw
  t->draw();                    // (4) call Triangle::draw
  Shape *p = &s;
  p->move(-100,-100);           // (5) call Shape::move; move s back
  p->draw();                    // (6) call Shape::draw; *slow*
  p = t;
  p->draw();                    // (7) call Shape::draw; *slow*
}
Static binding means the compiler determines the method to call based on the static types. If you're calling a method with static binding via a pointer to an object of type Shape, the compiler calls the method from type Shape.

This is distinct from what would happen if you said

  Square& s(construct,a,square);
  Shape q = s;
  q.draw();
In this case, object slicing occurs: what q holds is no longer a Square, just a Shape. When assigning pointers, you end up with a Shape pointer pointing to a Square. But lacking other instructions, the compiler still binds all methods at compile time, therefore to the methods of Shape. Virtual functions only apply when calling methods through a pointer or a reference, not directly from an object of the type!

In our example above, the behaviour was probably not intended. An alternative is to request the compiler to use dynamic binding to find the draw method for pointers:

class Shape {
public:
  virtual void draw() const;  // slow drawing routine
// ...
At run time, the object pointed to will be examined, and the appropriate method called. So at points (6) and (7) of executing f(), the dynamic type of the pointer is deduced, and the appropriate fast method executed.

A class is polymorphic if it has virtual functions or inherits from a class with virtual functions. The compiler must generate code for pointers to objects of a polymorphic class which can identify the type of the object and dispatch virtual functions to the appropriate function.

One way to implement virtual functions would be to attach to every object of polymorphic class a unique identifier (the compiler will generally hide this somewhere in the class' memory layout). For instance, if we attach the identifiers 100 to Shape, 101 to Square and 102 to Triangle, we can determine at run time which method to call at (6) and (7).

In practice, the popular implementation technique for virtual functions uses a vtable (or vtbl): every polymorphic class gets a table of function pointers to the appropriate method to call for each virtual function; the identifier attached to an object of polymorphic class is just a pointer to the vtable.

But there is no requirement to implement things in this manner! Indeed, given the example above, and no further inheritance from classes Square and Triangle anywhere in the whole program, a smart enough compiler could figure out the correct binding at compile time, and avoid the whole trouble of determining dynamic types at run time. By the "as if" rule, such an implementation would be legal. However, nothing near such sophistication appears to exist today.

Log in or register to write something here or to contact authors.