Allgemeines zu den Flags -> binäre Codierung:

Bei den Flags, von denen im folgenden die Rede sein wird, handelt es sich um einzelne Bits bzw. um Bitfelder, falls mehrere Formatbits zusammengefaßt werden. Dies bedeutet insbesondere, daß die Flags binär codiert sind, so daß man beim Setzen bzw. Abfragen bestimmter Bitkombinationen die binären Operatoren verwenden kann, um die Auswahl vorzunehmen.

Das Setzten bzw. Löschen der Formatflags kann über die beiden Elementfunktionen setf() und unsetf() erfolgen.
Für die Einstellungen des Formatstatus stehen zudem mehrere Operatoren zur Verfügung.

setf() zum Einstellen betsimmter Formatflags gibt es in zwei Varianten, d.h. genauer es existieren zwei überladene Instanzen für diese Funktion:

  setf(long);
  setf(long,long);

Das erste Argument kann dabei entweder ein Formatflag oder ein Formatbitfeld sein, das zweite Argument ist auf jeden Fall ein Formatbitfeld, das aus mehreren Formatflags betseht. Die zur Verfügung stehenden Formatflags und Format-Bitfelder wurden bereits im einzelnen vorgestellt, eine Zusammenfassung befindet sich im Anhang (#### LINK hinsetzen)
 

Anhang hat folgende Getsalt:

Formatflags:
 
Flag Bedeutung
ios::showbase Zahlenbasis ausgeben
ios::showpoint Format für Dezimalpunkt ausgeben
ios::dec Dezimalschreibweise
ios::hex Hexadezimalschreibweise
ios::oct Oktalschreibweise
ios::fixed Dezimalschreibweise für Fließkommawerte
ios::scientific Exponetialschreibweise für Fließkommawerte 
Format-Bitfelder:
Bitfeld Bedeutung Flags
ios::basefield ganzzahlige Basis ios::hex
ios::oct
ios::dec
ios::floatfield Fließkommaausgabe ios::fixed
ios::scientific

Zur Festlegung , wie die ganzzahlige Ausgabe zu erfolgen hat:

Die Umschaltung auf oktale Ausgabe ganzzahliger Werte erfolgt z.B. über die Anweisung:

  cout.setf(ios::oct, ios::basefield);

Die Elementfunktion setf(long,long) setzt zunächst das Format-Bitfeld -- in unserem Beispiel ios::basefield -- auf 0, d.h. alle Flags dieses Bitfeldes sind deaktiviert. Anschließend wird das im ersten Argument  -- hier: ios::oct -- angegebende Bitfeld gesetzt.
Neben dem Setzen des Flags an sich hat diese Funktion aber noch eine weitere Eigenschaft, die nicht unerwähnt bleiben sollte. setf() besitzt als Rückgabewert einen long-Integerwert, dem der vorherige Zustand entspricht. Damit kann der alte Zustand gespeichert werden und man besitzt eine einfache Möglichkeit, den alten Zustand der gesetzten Flags wiederherzustellen. Hierzu muß lediglich der Wert des alten Zustandes als erstes Argument in einem Aufruf von setf(long, long) angegeben werden:

  int wert=2044;
  long alte_basis;

  cout.setf(ios::oct, ios::basefield);
  cout << "Der Wert betraegt: " << wert << endl;    // Ausgabe in octal

  // alte Zahlenbasis speichern und Umschalten auf hexadezimale Darstellung
  alte_basis= cout.setf( ios::hex, ios::basefield);
  cout << "Der Wert betraegt: " << wert << endl;    // Ausgabe in hexadezimal

  // alte Einstellugen wiederherstellen
  cout.setf(alte_basis, ios::basefield);
  cout << "Der Wert betraegt: " << wert << endl;    // Ausgabe in octal

Man könnte sich nun die Frage stellen, wieso wir im obigen Beispiel für das Umschalten in den Hexadezimal-Modus nicht einfach den Befehl setf(long), also

  cout.setf(ios::hex);

verwendet haben. Der Grund hierfür ist folgende: bei dieser Instanz der setf()-Funktion mit nur einem Parameter wird der alte Zustand nicht aufgehoben. Hat man z.B. wie im Beispiel die Ausgabe ganzzahliger Werte zunächst auf oktal festgesetzt, d.h. genauer: ios::basefield auf Oktalschreibweise gesetzt, so wird bei Verwendung von cout.setf(ios::hex) nun zusätzlich die Hexadezimalschreibweise eingestellt, d.h. das Bitfeld ios::basefield ist auf mehr als eine Zahlenbasis festgesetzt! In diesem Fall wird standardmäßig die Dezimalschreibweise ausgewähl, und damit entspricht das erzeilte Ergebnis auf jeden Fall nicht dem gewünschten.

Ebenso einfach wie das Zurücksetzten auf eine alte Einstellung erfolgt auch das Zurücksetzten der Einstellungen auf die Defaultwerte:

  cout.setf(0, <format-bitfeld>);   // Zurücksetzten auf Default

Erläuterung zu putback():

Hiermit kann ein "ungewolltes Zeichen" in den Stream zurückgeschrieben werden, damit es an anderer Stelle noch zur Verfügung steht und gelesen werden kann. Ein kleines Beispiel soll dies verdeutlichen: Es wird Eingabe-Operator >> für einen benutzerdefinierten Typ -- hier wieder unser Beispiel eines Bruchs -- definiert:

  istream& operator>>(istream& str, bruch& b)
  /*
     Folgende Eingabeformate für einen Bruch sollen unterstützt werden (d stehe hierbei für double)::
          d               - nur Zähler angegeben
         (d)             -  nur Zähler angegeben, nun aber in Klammern gesetzt
         (d, d)          - ausführliche/vollständige Schreibweise mit zaehler, nenner (in Klammern gesetzt)

      Ein Bruch bestehe aus Zähler und Nenner, zudem stehe für die bruch-Klasse ein Konstruktor bruch(zaehler, nenner) bereit.
  */
  {
    double zaehler = 0, nenner = 1;     // Defaultwerte des Bruchs
    char c = 0;

    str >> c;     // Einlesen eines Characters aus dem Stream
    if (c == '(') {
      str >> zaehler >> c;   // Double in Variable zaehler einlesen, danach nächstes Zeichen lesen
      if (c == ',')  str >> nenner >> c;
      if (c != ')') str.clear(ios::badbit);    // Fehlerstatus des Streams setzen
    }
    else {
      str.putback(c);   // stelle das bereits eingelesenes Zeichen an den Stream zurück
      str >> zaehler;
    }

    // Falls Streamstatus in Ordnung ist, erzeuge den Bruch:
    if (str) br = bruch(zaehler,nenner);
    return br;
  }

Im Beispiel wird versucht, die verschiedenen Eingabeformate zu erkennen und Zähler und Nenner den Formaten entsprechend korrekt einzulesen. Die putback()-Methode wird hier dazu eingesetzt, daß erste gelesene Zeichen in den Stream zurückzustellen, falls es nicht die erste Klammer '(' war. Dann war dieses Zeichen nämlich schon der Zähler, den man abschließend einliest. Dieses Zurückstellen in den Stream ist deshalb nötig, weil aus dem Eingabestream zunächst ein Character-Typ eingelesen wurde. Stellt sich jedoch heraus, daß es sich nicht um '(' handelt, so muß es sich -- da ein Objekt der Klasse bruch eingelesen wird -- um einen double-Typ handeln. Eine einfache Zuweisung der Art

  zaehler = <eingelesenes Zeichen>;

ist daher nicht möglich, da es sich um zwei verschiedene Datentypen handelt. Folglich wird das eingelesen Zeichen wieder in den Stream gestellt, so daß es anschließend als double korrekt eingelesen werden kann.

Der implizite Zeiger this

Zugegeben: bisher haben wir keine Zeiger kennengelernt, dies wird erst im Kapitel ########?????##### nachgeholt. An dieser Stelle kommen wir aber dennoch nicht um die Erklärung eines Zeigers herum, dem impliziten this-Zeiger.Hinter einem Zeiger verbirgt sich eine spezielle Variable, deren Wert der Adresse eines Objektes im Speicher entspricht. Mit Hilfe eines Zeigers kann man auf ein Objekt indirekt zugreifen. Mehr wollen wir an dieser Stelle über Zeiger gar nicht verraten; merken Sie sich nur, daß man den this-Zeiger mit *this ansprechen kann.

Wozu brauche ich den this-Zeiger: Motivation ##### sieher bereits erstelltes Kapitel!!!

Was ist der this-Zeiger?
Nachdem wir anhand des Beispiels einen ersten Einsatzbereich des this-Zeigers gesehen haben, wollen wir uns nun ein wenig ausführliche mit diesem Konstrukt beschäftigen.
Jedes Objekt einer bestimmten Klasse verwaltet seine eigene Kopie der Datenelemente einer Klasse. Die Elementfunktionen müssen sich die verschiedenen Objekte einer Klasse jedoch teilen, sie rufen jeweils dieselbe Kopie einer bestimmten Elementfunktion auf. Jede Elementfunktion einer Klasse ist einmal vorhanden, d.h. sie ist nicht innerhalb des Klassenobjektes gespeichert. Wäre letzteres der Fall, würde die Anzahl der Funktionskopien mit jedem definierten Objekt enorm anwachsen.

Damit steht man vor einem Problem:
Wie ist die Elementfunktion, von der nur eine Instanz existiert, mit den einzelnen Datenobjekten der vesrchiedenen Objekte, die diese Funktion aufrufen, verbunden? Die Elementfunktion setze(int i, int j, double d) der matrix-Klasse muß ja auf die Elemente der verschiedenen matrix-Objekte, die diese Methode aufrufen, Zugriff haben, da sie diese u.U. verändern soll.

Die Lösung dieses Problems liegt in dem Zeiger this. Jede Elementfunktion einer Klasse enthält automatisch einen Zeiger auf ihren Klassentyp mit dem Namen this.Der this-Zeiger enthält dabei die Adresse desjenigen Klassenobjektes, über welches die Elementfunktion aufgreufen wurde. Und damit hat jede Elementfunktion auch Zugang zu den speziellen Datenelementen des aufrufenden Objektes.

Um die genaueren Möglichkeiten, die sich mit dem This-Zeiger ergeben, verstehen zu können, benötigt man  das Grundwissen über Zeigertypen (Pointer), daß aber erst in einem der nachfolgenden Kapiteln bereitgestellt wird. Wir beschränken uns daher auf den Einsatz des this-Zeigers, wie wir ihn im einführenden Beispiel kennengelernt haben. Mit
return *this;
kann das aufrufende Objekt von der aufgerufenen Methode zurückgeliefert werden.