Twitter und Facebook-Anbindung
X
Tweet Follow @twitterapi
!!! Anbindung an twitter und facebook öffnen !!!

Wenn Ihnen mein Online-Buch gefällt,
dann bedanken Sie sich doch mit einer kleinen Spende...

23.5 Ein - und Ausgabe (<< und >>)

23.5 Ein - und Ausgabe (<< und >>)

Eine sehr nette Funktionalität, ist das überladen der Serialisierungsoperatoren "<<" und ">>". In Kombination mit "cin" und "cout", kann man auf diese Art und Weise, Werte für Objekte einlesen lassen (immer nur ein Wert einlesbar) oder für das Objekt eine Ausgabe realisieren (dabei spielt es keine Rolle, ob mit Ein- und Ausgabe von oder auf die Konsole oder von oder aus Dateien gemeint ist).

Das klingt ja alles ganz spannend, aber bevor ich das zeige, muss ich ein wenig ausholen, denn diese zwei Operatoren kann man nicht als Methoden der Klasse implementieren, sondern muss sie als globale Funktionen bereitstellen. Damit jene dann auf das Objekt zugreifen können, müsste man normalerweise entweder entsprechende Getter und Setter bauen oder alle benötigten Sachen "public" machen, was unter Umständen nicht gewollt sein könnte. Um dies zu vermeiden, kann man eine "Freundschaft" mit der Klasse eingehen. Das klingt zwar jetzt ein wenig komisch, ist aber tatsächlich möglich. Man realisiert dies, indem man die Funktionsprototypen der entsprechenden Funktionen, welche auf die privaten Elemente eines Objektes zugreifen möchten, in die Klassendefinition mit aufnehmen und der Klasse mitteilt, dass dies "Freunde" sind. Dies sieht für das Beispiel so aus.

 1
 2
 3
 4
 5
 6
 7
					
#include <iostream>

// ...

		// Serialisieren
		friend std::ostream& operator<< (std::ostream&, const CInteger&);
		friend std::istream& operator>> (std::istream&, CInteger&);
					

Natürlich sollte man direkt in der CPP-Datei der Klasse, diese globalen Funktionen packen. Andernfalls könnten andere diese Schnittstelle nutzen, um Inhalte des Objektes zu manipulieren und somit das gesamte Konzept der OOP aus hebeln. Also, wenn Sie Freunde definiert, dann implementieren Sie sie an einer Stelle, an der man sie nicht ersetzen kann (In der CPP-Datei der Klasse könnte man sie zwar auch manipulieren, wenn jemand anderes diese Datei besitzt, aber dann hat er eh vollen Zugriff). Schauen wir uns nun die entsprechende Implementierung dieser zwei Methoden an.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
					
// Ein - und Ausgabe //////////////////////////////////////////////////////////
std::ostream& operator<< (std::ostream& oStream, const CInteger& oInt) {
	oStream << "Wert=" << oInt.m_iValue << endl;
	return oStream;
}

std::istream& operator>> (std::istream& oStream, CInteger& oInt) {
	oStream >> oInt.m_iValue;
	return oStream;
} // operator<< ///////////////////////////////////////////////////////////////
  
// ...

// Ermöglicht wird jetzt z.B. so etwas
CInteger oObjekt(5);

std::cin >> oObjekt;
std::cout << oObjekt;

// oder auch
CInteger* pZeigerAufObjekt = new CInteger(5);

std::cin >>* pZeigerAufObjekt;
std::cout << *pZeigerAufObjekt;

delete pZeigerAufObjekt;
					

Wie Sie in Zeile 1 und 6 sehr schön sehen, besitzen diese Funktionen nicht mehr den Namespace der Klasse und gehören somit nicht offiziell zu ihr. Wie Sie aber in Zeile 2 und 7 sehen, ist es trotzdem möglich, auf das private Attribut "m_iValue" zuzugreifen.

Zu dem Rückgabe - und dem ersten Übergabeparameter ist zu sagen, dass es sich hier um Referenzen auf ein Streamobjekt handelt, welches die Mechanismen von "cin" und "cout" wieder spiegeln. Der zweite Parameter ist dann unser Objekt. Da ich in der zweiten Funktion nur eine Ausgabe mache, kann ich getrost eine konstante Referenz übergeben, was bei der ersten Funktion nicht möglich ist, da ich das Objekt ja manipuliere, also den eingelesenen Wert eintragen will.

Zum Seitenanfang
Zum Inhaltsverzeichnis

© Copyright by Thomas Weiß, 2009 - 2012