Virtualität (2/4)

virtuelle Funktionen

Angenommen die Implementierung der Methode verschiebe(int, int) des Grafikobjekts sei wie folgt:

  void grafikobjekt::verschiebe(int x, int y)
  {
    loesche();
    xpos = x;
    ypos = y;
    zeichne();
  };

Die Funktion löscht erst das Objekt vom Schirm, ändert die Koordinaten und zeichnet das Objekt neu. Aufgrund der Allgemeinheit brauchen wir diese Funktion auch für abgeleitete Klassen nicht neu zu definieren, da wir die zusätzlichen Eigenschaften in neuen zeichne()-Methoden berücksichtigen. Dabei taucht ein Problem auf:

  kasten K;
  K.verschiebe(11, 7);   // grafikobjekt::verschiebe() -> grafikobjekt::loesche()

Da verschiebe() nur in grafikobjekt definiert ist, wird diese Funktion aufgerufen. Damit befinden wir uns auf der Ebene eines Grafikobjekts. Die jetzt folgenden Aufrufe von loesche() und zeichne() kennen aber nicht die Herkunft des Aufrufs und beziehen sich nunmehr auf ein Grafikobjekt. Die Information eines Kastens geht verloren: Es wird, wie in grafikobjekt vorgesehen, nichts gelöscht und nichts gezeichnet. Dennoch hat der Kasten eine neue interne Position.

Die Lösung des Problems besteht darin (wie es schon in den Beispielen durchgeführt wurde), entsprechende Funktionen, die sonst nicht richtig zugeordnet werden können, als virtual zu deklarieren. Das hat zur Folge, daß eine Zuordnungstabelle erstellt wird, die bei Aufrufen immer die Funktion aus der richtigen Klasse zuordnet. Diese Tabelle wird automatisch angelegt und später auch wieder automatisch gelöscht und aus dem Speicher entfernt.