non-member function and operators

Nicht immer kann Operator als member–function ( d.h. Methode innerhalb der Klasse) implementiert werden, z.B: Operation 3–Vector \bgroup\color{red}$\times$\egroup Scalar \bgroup\color{red}$ \Leftrightarrow$\egroup Scalar \bgroup\color{red}$\times$\egroup 3–Vector

My3Vector a(1,1,0);
My3Vector c = a * 3.; // c = a.scale(3.)
My3Vector c = 3. * a; // und nu ?

Deklaration ausserhalb der Klasse also globale Funktion:

My3Vector operator * ( double & c, My3Vector & v );

Für  My3Vector c = a * 3.; beides möglich:

Member:

 My3Vector operator * ( double & c ) ;

Non–member:

My3Vector operator * ( My3Vector & v, double & c );

Ähnliches Problem z.B für stream ( << ) Operator: cout << a ;

Links von Operand steht Objekt von Typ ostream, rechts Typ My3Vector. ostream fester Bestandteil von C++ I/O, weiss nix von My3Vector und nicht vom User erweiterbar !

Einzige Alternative ist non-member Funktion:



// Deklaration in My3Vector.h
std::ostream & operator << ( std::ostream &, const My3Vector &);

// Implementation in My3Vector.cpp
#include <iostream>
std::ostream & operator << ( std::ostream &s, const My3Vector &v)
{
  s << "(" << v.x <<","<< v.y <<","<< v.z <<")";
  return s;
}


Hierbei muss Referenz auf Objekt vom Typ ostream zurückgegeben werden, damit Aneinanderreihen cout < funktioniert

Aber:

Non-member functions haben keinen Zugriff auf  private data members.

Ausweg:

  friend std::ostream &operator << ( std::ostream &s, My3Vector &p);


Vergleich C++ und C

Mit den My3Vectors soweit jetzt diskutiert kann man sehr einfach und effizient Code für Dreier-Vektor Manipulationen schreiben, z.B. Vektoren addieren, mit Skalar multiplizieren, ...
  My3Vector a(1,1,-1), b(2,0,3);
  a += 3.*b;

Das operator-overloading macht dies besonders elegant. Aber auch wenn man darauf verzichtet (Java) ist es immer noch recht kompakt:
  a.Increment( b.Scale(3.) );

Wie würde man's ohne Klassen/Objekte in C lösen ?

Variante 1: Direkt kodieren:



  double a[3] = { 1, 1, -1 };
  double b[3] = { 2, 0, 3 };
  int i;
  for ( i=0; i<3; i++ ) {
    a[i] += 3. * b[i];
  }


Variante 2: Entsprechende C Funktionen definieren/verwenden:



int main()
{
  double a[3] = { 1, 1, -1 };
  double b[3] = { 2, 0, 3 };
  double tmp[3];
  Scale3Vector( b, 3., tmp );
  Add3Vector( a, tmp, a );
}
void Scale3Vector( double vin[], double scale, double vout[] )
{ int i;
  for ( i=0; i<3; i++ ) {
    vout[i] = scale*vin[i];
  }
}
void Add3Vector( double v1[], double v2[], double vout[] )
{int i;
  for ( i=0; i<3; i++ ) {
    vout[i] = v1[i] + v2[i];
  }
}


Geht natuerlich auch in C, aber unhandlich, kryptisch, fehleranfällig, ...