Version [22776]
Dies ist eine alte Version von ObjProg04Operator erstellt von RonnyGertler am 2013-03-29 00:33:18.
Objektorientierte Programmierung - Kapitel 4 - Operator - Überladung
Inhalte von Dr. E. Nadobnyh
4.1. Grundlagen und Regeln
Operator-Überladung
Ein Operator ist überladen, wenn er je nach Typ der Operanden eine unterschiedliche Bedeutung hat.
Die meisten Operatoren für eingebauten Datentypen sind schon überladen.
Beispiel:
double a, b; short x, y;
a*b; x*y; //verschiedene Algorithmen
Operatorfunktion
In C++ gibt es die Möglichkeit , Operatoren für die Klassen zu definieren.
Eine Operatorfunktion ist eine Funktion mit einem besonderen Namen. Der Name der Operatorfunktion beginnt mit dem Schlüsselwort operator, dem das Operatorsymbol folgt. Ausdrücke mit Operatoren sind intuitiver und daher schneller zu erfassen als Ausdrücke mit Funktionsaufrufe.
Zwei Definitionsmöglichkeiten
Eine Operatorfunktion kann entweder als globale Funktion oder als Methode einer Klasse definiert werden.
1) Globale Operatorfunktion
class Bruch{ };
Bruch operator+ (Bruch, Bruch );
bzw. Operatorfunktion als Methode
class Bruch
{ public:
Bruch operator+ (Bruch x);
};
4. Operator-Überladung
Aufruf der Operatorfunktion
Der Operator-Aufruf wird in einen Funktionsaufruf umgewandelt:
1) entweder in den Aufruf der globalen Operatorfunktion,
2) oder in den Aufruf der Operatormethode.
Mehrdeutigkeit
Wenn Compiler mehr als eine Aufrufmöglichkeit findet, wird der Aufruf bemängelt.
⇒ Demo 1.
Globale Operatorfunktion
class Bruch; //Vorwärtsdeklaration
Bruch operator+(Bruch a, Bruch b); //Deklaration
class Bruch
{ //Freundschaftserklärung
friend Bruch operator+(Bruch a, Bruch b);
};
main()
{ Bruch a, b, c;
c = a + b; //Aufruf
c=operator+(a,b); //identisch
}
Bruch operator+(Bruch a, Bruch b); //Deklaration
class Bruch
{ //Freundschaftserklärung
friend Bruch operator+(Bruch a, Bruch b);
};
main()
{ Bruch a, b, c;
c = a + b; //Aufruf
c=operator+(a,b); //identisch
}
⇒ Demo 1.2
Operatormethode
class Bruch
{ public: Bruch operator+(Bruch b);
};
main()
{ Bruch a, b, c;
c = a + b; //Aufruf
c=a.operator+(b); //identisch
}
{ public: Bruch operator+(Bruch b);
};
main()
{ Bruch a, b, c;
c = a + b; //Aufruf
c=a.operator+(b); //identisch
}
Operanden
Der zweistellige Operator hat zwei Operanden. Der erste Operand ist ein Objekt, für das die Methode aufgerufen wird.
⇒ Demo 3.
Einsatzregeln
1) Es können bis auf wenige Ausnahmen alle Operatoren überladen werden.
2)Der Funktionsname besteht aus dem Schlüsselwort operator und dem Operatorzeichen.
3) Es können die übliche Operatoren überladen werden (z.B. *, +=, usw.).
Eine Definition von neuen Operatoren ist nicht möglich, z.B. neuen Operator ** zum Potenzieren. Andere Zeichen wie $ usw. sind nicht erlaubt.
⇒ Demo 4. C++ Operatoren
4) Wenigstens ein Argument der Operatorfunktion muss ein class –Objekt sein, oder die Operatorfunktion muss eine Methode sein. Die Bedeutung der Operatoren für Standard-Typen lässt sich nicht umdefinieren.
5) Die Anzahl der Operanden eines Operators (Stelligkeit) kann nicht geändert werden, d.h. ein unärer Operator bleibt unär.
6) Einige Operatoren (z.B.: +, -, * ) können getrennt unär und binär überladen werden.
⇒ Demo 5.
7) Der Operator-Aufruf wird in einen Funktionsaufruf umformuliert.
8) Die vorgegebenen Vorrangregeln können nicht verändert werden.
9) Die Reihenfolge der Auswertung (von links oder von rechts) bei der Operatoren mit gleicher Priorität bleibt erhalten.
10) Überladene Operatoren können keine Default-Parameter haben. (Eine Ausnahme ist der Funktionsoperator.)
⇒ Demo 6 + Demo 7.
Einzelne Operatoren sind nicht überladbar:
Operator | Bedeutung |
sizeof
. .* :: ?: |
Größe von Objekten
Zugriffsoperator (Strukturen, Unions, Klassen) Zugriffsoperator für Elementzeiger Bereichsoperator Auswahloperator |
Operatoren, die nur als Methoden überladen werden können
Operator | Bedeutung |
= [ ] ( ) -> (Typ) |
Zuweisung Indizierung Funktionsaufruf bzw. Funktionsoperator Elementzugriff für Zeiger Typumwandlungsoperator |
4.2. Symmetrie der Operatoren
Symmetrische Operatoren
Einige binäre Operationen z.B. Addition sind kommutativ und ihre beide Operanden sind „gleichberechtigt“.
Beispiel:
Bruch a, b, c;
c=a+b;
c=b+a;
Gemischte Datentypen
Die Verwendung der Operanden vom Datentyp int soll auch möglich sein.
Beispiel:
Bruch a, b, c;
c=a+5;
c=5+a;
Symmetrie der globalen Operatorfunktionen
a) Ohne Konvertierungskonstruktor
Um gemischte Datentypen zu erlauben, kann man noch zwei globalen Operatorfunktionen entwerfen:
Bruch operator+(Bruch a, Bruch b);
Bruch operator+(Bruch a, long b);
Bruch operator+(long a, Bruch b);
b) Mit Konvertierungskonstruktor
Der Compiler konvertiert implizit den aktuellen
Parameter vom Typ long in Typ Bruch.
Bruch operator+(Bruch a, Bruch b);
Bruch (long x);
⇒ Demo 8.
Asymmetrie der Operatormethode
Die Symmetrie geht verloren, wenn die Operatorfunktion als Methode implementiert wird.
Beispiel: Addition einer rationalen und einer ganzen Zahl
Aufruf | Operatormethode |
c = a + 3; c = a.operator+(3); |
Bruch Bruch::operator+(int x); |
c = 3 + b; c = 3 .operator+(b); |
unmöglich |
CategoryObjProg