Postfix-Operatoren

Postfix-Operatoren sind eine Besonderheit in C++, es gibt nämlich nur zwei dieser Sorte. Dies ist zum einen der Inkrement-Operator (++) und der Dekrement-Operator (–).

Alle Prefix-Operatoren erhalten klassenintern kein Argument, bzw. global (also außerhalb der Klassendefinition) definiert ein Argument, wie es im Kapitel 'unären Operatoren' beschrieben ist.

Da Inkrement- und Dekrement-Operator jedoch sowohl als Prefix- und als Postfix-Operator auftreten konnte man so in frühen C++-Versionen nur den Prefix-Operator überladen. Es gab keine keine Schlüsselworte, um die beiden operator ++-Varianten zu unterscheiden.

Schlüsselwörter gibt es auch heute noch nicht, man hat eine andere Lösung gefunden, um eben der Sprache eben keine Schlüsselwörter hinzufügen zu müssen: Man überlädt den operator ++ mit einem zusätzlichen Integer-Argument, das aber keine Bedeutung hat:

class Fraction
{
  ...
    Fraction & operator ++( void ); // Prefix - wie gewohnt
    Fraction operator ++( int );    // Postfix
}

Zu Beachten ist hier, dass die Prefix-Variante eine Referenz liefern darf, weil sie als Setter ein existierendes Objekt verändert und eine Referenz auf dieses existierende Objekt liefern kann. Die Postfix-Variante ist gleichzeitig Setter (sie verändert das Argument), wie auch Getter(sie liest den Wert aus und liefert ein neu produziertes Ergebnis). Wichtig ist hier aber, dass eine vollständinge temporäre Variable zurückgegeben wird, nicht nur eine Referenz (siehe dazu auch 'Getter erlauben keine Referenzen' unter Infix-Operatoren).

Vorteile der Prefix-Variante

Grundsätzlich ist die Prefix-Variante zu bevorzugen, die als Setter das gegeebene Argument verändern, die Postfix-Variante als Getter jedoch ein neues Objekt erzeugt:

int a = 4;
 
int b = a++; // Postfix : a++
int c = --a; // Prefix  : --a

Schauen wir uns zunächst an, was passiert: b wird mit 4 beschrieben und a wird um eins erhöht (also ist a gleich 5). Anschließend wird a um eins verkleinert (a ist gleich 4) und zu guter Letzt wird c mit dem Wert von a beschrieben. c erhält also ebenfalls den Wert 4.

Es ist wichtig, wie dies passiert: Zuerst werden die Inkrement (++)-, bzw. Dekrement (–)-Operatoren ausgeführt. Das Ergebnis dieser Operatoren wird anschließend zugewiesen.

Die Prefix-Operator ist so definiert, dass zuerst addiert bzw. subtrahiert wird und dann das Ergebnis zurückgegeben wird. Beim Postfix-Operator steht das Ergebnis fest, bevor gerechnet wird, es wird nämlich der ursprüngliche Wert zurückgegeben, bevor er verändert wird. Also muss man den alten Wert zwischenspeichern. Schauen wir uns das ganze als Sourcecode an:

class IntegerValue
{
  private:
    int Value;
  public:
    ...
    inline IntegerValue & operator ++ ( void )  // Prefix
    {
      Value += 1;
      return *this;
    }
    inline IntegerValue operator ++ ( int )  // Postfix
    {
      IntegerValue result( *this );
      ++(*this)
      return result;
    }
};

Man sieht, dass die Postfix-Variante deutlich aufwändiger ist als Prefix-Variante und daher auch vom Programmierer bevorzugt verwendet werden soll (ebenso, wie die Zuweisungsoperatoren +=, *=, …).

Gelegentlich hört man, dass aus diesem Grund 'C++' auch besser '++C' heißen sollte. Andere behaupten, dass 'C++' der richtige Name sei: Es ist aufwendiger als 'C', aber es kommt auch kein anderes Ergebnis bei rum. ;-)