Die Shift-Operatoren

Die Shift-Operatoren werden wie alle binären infix Operatoren überladen:

class Fraction
{
  ...
    inline Fraction & operator <<( int shift )
    {
      Numerator <<= shift;
    }
    Fraction operator >>( int );
    {
      Numerator >>= shift;
    }
}

Die meisten Klassen wollen aber gar nicht 'geshiftet' werden, wie verschiebt man zum Beispiel ein Rechteck? Nach oben bzw. unten oder doch lieber nach links und rechts. Oder verändert es durch die Shift-Operatoren seine Fläche.Das alles ist nicht sonderlich offensichtlich für einen Entwickler, der diese Klasse verwenden möchte. Shift als Import- und Export-Operator

Weit verbreitet ist allerdings, die Shift-Operatoren als Import- und Export-Operatoren zu verwenden, so dass sie auf Streams geschrieben werden, oder von einem Stream Daten aufnehmen können.

Fraction f( 1, 2 );
 
cout << f;

In diesem Fall steht der Stream grundsätzlich rechts, das bedeutet, dass der Operator nicht als Memberfunktion definiert werden kann. Stattdessen muss er global definiert werden als 'friend'deklariert werden, wenn er auf protected oder private Elemente der Klasse zugreifen muss.

class Fraction
{
  friend Fraction & operator <<( ostream & lhs, Fraction & rhs );
 
  private:
    int Numerator;
    int Denominator;
  public:
    ...
};
ostream & operator *=( ostream & lhs, Fraction const & rhs )
{
  lhs << Numerator << "/" << Denumerator;
  return lhs;
}

Man sollte grundsätzlich die Referenz auf den Stream zurückgeben, um Ausgaben wie gewohnt zusammenstellen zu können:

Fraction f( 1, 2 );
 
cout << f << "* 2 = " << ( 2 * f ) << endl;

Entsprechendes gilt für den Import-Operator (operator »).