In
Kapitel 22 (Operatorfunktionen) haben wir den Additionsoperator für Complex-Objekte
versuchsweise als Mitgliedsfunktion von Complex deklariert:
class Complex
{
public:
Complex( double re_in, double im_in = 0.0 )
Complex operator + ( const Complex& );
/* ... weitere Mitglieder ... */
};
Schreibt man nun z.B.
Complex c2, c3;
c3 = c2 + 1.0; // implizite
Konvertierung zu Complex
erfolgt wie erwartet eine implizite Konvertierung des double-Wertes
1.0 zu
einem temporären Complex-Objekt,
das dann als Argument für den Additionsoperator verwendet wird.
Ist die
Anweisung
c3 = c2 + 1; // ???
Diese implizite Konvertierung funktioniert nur für die rechte Seite
in der Anweisung. Schreibt man dagegen
c3 = 1.0 + c2; // Fehler! keine
implizite Konvertierung zu Complex
erhält man einen Syntaxfehler. Der Grund ist, dass die Notation
z = x + y;
der Notation
z = x.operator + ( y );
entspricht, wenn die Operatorfunktion als Mitgliedsfunktion implementiert
ist. Der Typ double
ist jedoch keine Klasse und hat daher auch keine Mitgliedsfunktionen.
Um implizite Konvertierungen auch für die linke Seite eines Operatorausdrucks
möglich zu machen, muss der Operator mit Hilfe einer globalen Operatorfunktion
implementiert werden:
Complex operator + (
const Complex&, const Complex& );
Nun können implizite Konvertierungen für beide Parameter erfolgen,
die Anweisung
c3 = 1.0 + c2; // nun auch hier
implizite Konvertierung zu Complex
ist nun syntaktisch korrekt.
Es ist also günstiger, den Operator + über eine globale
Operatorfunktion zu implementieren. Das gleiche gilt für alle symmetrischen
Operatoren wie *, ==, != etc. Alle diese
Operatoren ändern außerdem keines der Argumente, sondern geben das Ergebnis in
einem (neuen) Objekt zurück.
Im Gegensatz dazu stehen die Operatoren, die auf ein Objekt wirken
und dieses verändern. Zu ihnen gehören z.B. die erweiterten Zuweisungsoperatoren
(+=, -= etc), sowie Inkrement-
und Dekrementoperator (++
bzw. --).
Diese Operatoren werden deshalb grundsätzlich als Klassenmitglieder implementiert.