next up previous
Nächste Seite: Genügt wirklich Konstruktor und Aufwärts: Können wir die mathematische Vorherige Seite: Können wir die mathematische

Überladen von Operatoren

Es gibt in C++ eine Menge von Operatoren:


 +   -   *   /   %       // arithmetisch
 ~   &   |   ^  <<  >>   // bitweise
++  --                   // In/Dekrement
 +   -                   // Vorzeichen
 =  +=  -=  *=  /=  %=   // Zuweisung
&=  |=  ^= <<= >>= 
==   <   >  <=  >=  !=   // Vergleiche
 !  &&  ||               // logisch
 *   &  ->   .           // Adressen
 ,  ()  []  ?:  ::       // spezielle
new delete sizeof
#  ##                    // Praeprozessor

  1. alle C++-Operatoren außer ?:, . , * (Dereferenzierung), ::, #, ##, sizeof können überladen werden
  2. überladen werden können insbesondere auch new und delete
  3. es gibt unäre und binäre Operatoren, unäre haben genau einen Operanden, binäre haben genau drei Operanden, (in C/C++ gibt es auch einen trinären Operator: ?:)
  4. die Vorrangregeln bleiben erhalten
  5. die Abarbeitungsreihenfolge bleibt erhalten
  6. es können keinen neuen Operatoren erfunden werden
  7. eingebaute C++-Operatoren für Standardtypen können nicht überladen/verändert werden

Klassendefinition:


class CVector {
  ...
  CVector operator+(
    const CVector& right_operand
  ) const;
  ...
}

d.h. wir deklarieren einen Operator + als binäre Operation, welche implizit (als Objekt der aufgerufenen Memberfunktion) den linken Operanden und explizit als Parameter den rechten Operanden erhält.

Vorstellungsmöglichkeit: Wir hätten auch eine Memberfunktion VectorAdd definieren können:


class CVector {
  ...
  Vector VectorAdd(const CVector& right_operand) const;
  ...
};
welche dann wie folgt benutzt worden wäre:

CVector a,b,c;

c = a.VectorAdd(b);     // c = a + b
Hier ist der linke Operand a das Objekt, dessen Memberfunktion VectorAdd mit Operanden b aufgerufen wird.

Mit der Operatorschreibweise gilt folgende Vorstellung: Der Compiler erkennt zuerst den linken Operanden, danach den Operator, und weiß dann, welche Klassegemeint ist (Typ des linken Operanden), und sucht dann eine Memberfunktion (hier operator+), deren Parameter mit dem Typ des rechten Operanden übereinstimmt.

Genau genommen, folgende beiden Zeilen sind äquivalent und können beide verwendet werden:


c = a + b;
c = a.operator+(b);

Implementierung:


CVector CVector::operator+(
  const CVector& right_operand
) const {
  CVector v;     // construction of a CVector

#ifdef _DEBUG
  if(dimension!=right_operand.dimension) {
    cout << "fatal error: dimensions of vectors differ\n";
    exit(1);
  }
#endif
  for(int i=0;i<dimension;i++)
    v.vector[i]=vector[i]+right_operand.vector[i];
  return v;
}                // destruction of the CVector v

Die Funktion ist const deklariert, d.h. sie kann keine Member-Variable ändern.



\fbox {\centerline{\parbox{0.9\textwidth}{
{\bfseries Regel:} Wir implementieren Member-Funktionen wo immer m\uml {o}glich als
{\tt const}}}}

.


next up previous
Nächste Seite: Genügt wirklich Konstruktor und Aufwärts: Können wir die mathematische Vorherige Seite: Können wir die mathematische

1999-12-13