Sie sind auf Seite 1von 41

Übersicht

3. Erste Schritte zur Objektorientierung


3.1 Ein-/Ausgabe über Streams (Teil 1)
3.2 Erzwungene Typkonversion (Teil 1)
3.3 Dynamische Speicherverwaltung mit new und delete

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.1 Ein-/Ausgabe über Streams

 Ein-/Ausgabe über Streams (Teil 1)


– In C++ wird jedem Standardkanal (stdin,
stdout, stderr) ein Ein-/Ausgabeobjekt
zugeordnet

Programm

stdin cin cout stdout

cerr clog

stderr
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.1 Ein-/Ausgabe über Streams

 Ein-/Ausgabe über Streams


– Aufbau der Objekte mit Hilfe einer umfangrei-
chen Klassenbibliothek
• D.h. auch in C++ ist die Ein-/Ausgabe nicht Bestandteil
der Sprache, sondern der Standardbibliothek
ANSI C C++ Objekttyp Einordnung
#include <stdio.h> #include <iostream> iostream Stream I/O
printf(...); cout << ... ; ostream
scanf(...); cin >> ... ; istream
#include <stdio.h> #include <fstream> fstream File I/O
out = fopen(...); ofstream out(...); ofstream
fprintf(out, ...); out << ... ;
in = fopen(...); ifstream in(...); ifstream
fscanf(in, ...); in >> ... ;
#include <stdio.h> #include <strstream> strstream String I/O
ostrstream otxt(...); ostrstream
sprintf(...); otxt << ... ;
istrstream itxt(...); istrstream
sscanf(...); itxt >> ....;
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.1 Ein-/Ausgabe über Streams

 Ausgabeströme - Standardausgabe
– Vordefinierte Output-Stream-Objekte
cout
cout gepufferte Standardausgabe
ostream-
Objekte cerr
cerr ungepufferte Standardfehlerausgabe
clog
clog gepufferte Standardfehlerausgabe
– Ausgabeoperator
Methode: Ausgabeoperator (inserter) << <iostream.h>
Aufruf: ostream-Objekt << Ausdruck [<< Ausdruck [...]];
Wirkung: Der Ausdruck wird bewertet, konvertiert und formatiert als
Zeichenkette ausgegeben. Eine Verkettung mehrerer
Ausgaben ist möglich.

• Beispiel
cout << 3 << "-mal schwarzer Kater " << endl;

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.1 Ein-/Ausgabe über Streams

 Ausgabeströme
– Überladung des Ausgabeoperators z.B. für fol-
gende Standarddatentypen
ostream& operator<<(bool)
ostream& operator<<(char)
ostream& operator<<(unsigned char)
ostream& operator<<(const char*)
ostream& operator<<(short)
ostream& operator<<(unsigned short)
ostream& operator<<(int)
ostream& operator<<(unsigned int)
ostream& operator<<(long)
ostream& operator<<(unsigned long)
ostream& operator<<(float)
ostream& operator<<(double)
ostream& operator<<(long double)
ostream& operator<<(void*)
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.1 Ein-/Ausgabe über Streams

 Ausgabeströme - Weiteres Beispiel


#include <iostream>
using namespace std;
void main(void)
{
char* str = "Hallo";
int zahl = 0x815;
float zahl2 = (float)47.11;
cout << "*str = " << str << "\n";
cout << " str = " << (void*)str << "\n\n";
cout << " zahl = " << zahl << "\n";
cout << " zahl2 = " << zahl2 << "\n";
}

– Ausgabe?

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.1 Ein-/Ausgabe über Streams

 Standardausgabeströme und Pufferung


– Ausgabe nach cout und clog erfolgt erst bei
Leerung des Ausgabepuffers (flush)
– Leerung des Puffers in folgenden Fällen
• Puffer ist voll
• Ausgabe erfolgt nach cerr
• Eingabe erfolgt über cin
• Puffer wird ausdrücklich geleert durch
– flush,
– endl oder
– Programmende

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.1 Ein-/Ausgabe über Streams

 Pufferung - Beispiel
#include <iostream>
#include <time.h> – In welchen
using namespace std; zeitlichen
void main(void)
{
Abständen
// verstrichene Sekunden seit 1.1.1970 erfolgt die
time_t Start = time(NULL);
Ausgabe ?
clog << " Zunaechst nach clog,\n";
// 10 Sekunden warten
while (time(NULL) < Start+10);
cerr << " dann nach cerr,\n";
// weitere 10 Sekunden warten
while (time(NULL) < Start+20);
cout << " zuletzt nach cout.\n";
// weitere 10 Sekunden warten
while (time(NULL) < Start+30);
}
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.1 Ein-/Ausgabe über Streams

 Formatierte Ausgabe
– Alternativen
• Manipulatoren
• Funktionen/Methoden der Ausgabeobjekte
– Manipulatoren
• Es existieren parameterlose Manipulatoren und solche mit
Parametern
• Parametrisierte Manip. benötigen eine Header-Datei
#include <iomanip>
• Manip. werden durch „<<“ in den Ausgabestrom eingefügt
• Manip. sind Zeiger auf Memberfunktionen der IO-Objekte.
– Die Shiftoperatoren sind auch für diese Zeiger überladen
 Es wird eine Memberfunktion durch das Einfügen eines
Manipulators aufgerufen
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.1 Ein-/Ausgabe über Streams

 Formatierte Ausgabe - Manipulatoren I


Manipulator Wirkung/Verwendung
hex, dec, oct Ganze Zahlen werden hexadezimal, dezimal oder oktal ausgegeben.
cout << hex << 127 << "\n";
7f cout << dec << 127 << "\n";
127 cout << oct << 127 << "\n";
177
boolalpha (noboolalpha) Gibt für true oder 0 true aus und für false oder 0 false.
true cout << boolalpha << bool(1);
endl Zeilenumbruch und Leerung des Ausgabepuffers
cout << "Das war's!" << endl;
ends '\0' anhängen; Leerung des Ausgabepuffers (Stringstreams)
cout << "Das war's!" << ends;
flush Leeren des Ausgabepuffers
cout << flush;
setw(int x) Nur für die folgende Ausgabe wird die durch x festgelegte
Feldweite verwendet. Die Ausgabe erfolgt rechtsbündig.
127 cout << setw(7) << 127 << endl;
setfill(char x) Legt für die folgenden Ausgaben ein Füllzeichen fest.
Standardmäßig wird das Leerzeichen als Füllzeichen ausgegeben.
cout << setfill('.'); // . als Füllzeichen
....127 cout << setw(7) << 127 << endl;
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.1 Ein-/Ausgabe über Streams

 Formatierte Ausgabe - Manipulatoren II


Manipulator Wirkung/Verwendung
setiosflags(int) Setzt bestimmte Formatbits zur Manipulation der Ein-/Ausgabe. Die
wichtigsten sind:
cout << setiosflags(ios::???) << 3.141;
ios::dec dezimal
ios::hex hexadezimal
ios::oct oktal
mit setw(7)
ios::left linksbündig
3.141
3.141 ios::right rechtsbündig (standard)
+3.141 ios::showpos + vor pos. Zahlen
ios::uppercase Hex und Exp. mit Großbuchstaben
3.141000e+000 ios::scientific wissensch.. Format d.ddddddeddd
3.141000 ios::fixed Festkommaformat d.dddddd
resetiosflags(int) Setz die angegebenen Flags wieder zurück.
setprecision(int x) Legt zusammen mit ios::fixed die Anzahl der Nachkommastellen
für alle nachfolgenden Gleitpunktausgaben fest (Standard ist 6).
cout << setiosflags(ios::fixed)
3.14 << setprecision(2) << 3.14156;

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.1 Ein-/Ausgabe über Streams

 Formatierte Ausgabe
– Direkte Verwendung der Memberfunktionen
• Diese greifen auf abfragbare und veränderbare Format-
bits (ios::flags) zu
• Beispiele für Synonyme
cout.fill('.');  cout << setfill('.');
cout.width(10);  cout << setw(10);
cout.setf(ios::left);  cout << setiosflags(ios::left);
cout.unsetf(ios::left);  cout << resetiosflags(ios::left);
cout.precision(3);  cout << setprecision(3);

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.1 Ein-/Ausgabe über Streams

#include <iostream>
 Forma- #include <iomanip>
using namespace std;
tierte
void main(void)
Aus- {
char *obstArr[] = {"Apfel", "Birne", "Banane"};
gabe float preisArr[] = {0.25F, 0.30F, 0.50F};
float mwst = 0.19F;
– Beispiel
cout.width(45);
• Ausgabe? cout << "Unser Angebot\n\nObst\t\tNetto\tBrutto"<<endl;
for (int count = 0; count < 3; count++)
{
cout.fill('.');
cout << setiosflags(ios::left)<< setw(16)
<< obstArr[count]
<< resetiosflags(ios::left) << setw(5)
<< fixed << setprecision(2) << setfill(' ')
<< preisArr[count]
<< setw(9)
<< preisArr[count]*(1+mwst) << endl;
}
}
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.1 Ein-/Ausgabe über Streams

 Formatierte Ausgabe
– Beispiel
#include <iostream>
using namespace std;
void main(void)
{
int a = 1, b = 2, c = 3;
cout << "A + B + C = " << a + b + c << endl;
cout << "A ^ B | C = " << (a ^ b | c) << endl;
cout << " A << B = " << (a << b) << endl;
}

• Ausgabe? A + B + C =
A ^ B | C =
A << B =

• Klammern notwendig?
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.1 Ein-/Ausgabe über Streams

 Weitere Ausgabefunktionen
– Methode zur Einzelzeichenausgabe
Methode: ostream& put(char ch); <iostream>
Wirkung: Die Funktion put gibt das vorgegebene Zeichen ch aus.

– Methode zur blockweisen Zeichenausgabe


Methode: ostream& write(const char*, int n); <iostream>
Wirkung: Die Funktion write überträgt n Zeichen aus einem Puffer in den
Ausgabestream. (Sie wird auch für das blockweise Schreiben in
Binärdateien verwendet.)

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.1 Ein-/Ausgabe über Streams

 Eingabeströme - Standardeingabe
– Vordefiniertes Input-Stream-Objekt (istream)
• cin
cin Standardeingabeobjekt zum Einlesen von Daten
über die Tastatur
– Eingabeoperator
Methode: Eingabeoperator (extractor) >> <iostream>
Aufruf: istream-Objekt >> L-Wert [>> L-Wert [...]];
Wirkung: Die eingegebenen Daten werden in den Typ der übergebe-
nen Variablen konvertiert (übergeben werden Referenzen).
Führende Whitespaces (Leerzeichen, Tab, Zeilenumbruch)
werden überlesen. Die folgenden Zeichen werden solange
in den gewünschten Typ konvertiert, bis ein Zeichen auf-
tritt, das nicht konvertiert werden kann. Dieses und alle
weiteren Zeichen verbleiben im Eingabepuffer.

• Beispiel cin >> var >> zahlArr[3];


OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.1 Ein-/Ausgabe über Streams

 Eingabeströme
– Überladung des Eingabeoperators z.B. für fol-
gende Standarddatentypen
istream& operator>>(bool&)
istream& operator>>(char&)
istream& operator>>(unsigned char&)
istream& operator>>(char*)
istream& operator>>(short&)
istream& operator>>(unsigned short&)
istream& operator>>(int&)
istream& operator>>(unsigned int&)
istream& operator>>(long&)
istream& operator>>(unsigned long&)
istream& operator>>(float&)
istream& operator>>(double&)
istream& operator>>(long double&)

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.1 Ein-/Ausgabe über Streams

 Formatierte Eingabe - Manipulatoren


– Alle istream- und ostream-Objekte sind
durch Ableitung aus ios entstanden
• Die meisten der Manipulatoren für Ausgabeströme gelten
hier ebenfalls
Manipulator Wirkung/Verwendung
hex, dec, oct Die dem Manipulator folgende Zahl wird hexadezimal,
dezimal oder oktal interpretiert.
cin >> hex >> iA;
skipws/noskipws Führende Whitespaces werden überlesen/nicht überlesen.
setzt Flag ios::skipws / löscht Flag ios::skipws
setw(int x) Nur für die folgende Eingabe wird die durch x festgelegte
Feldweite verwendet (max x-1 Zeichen werden gelesen).
cin >> setw(6) >> pcString;
setiosflags(int) Setzt bestimmte Flags zur Manipulation der Ein-/Ausgabe.
cin >> setiosflags(ios::skipws);
resetiosflags(int) Setz die angegebenen Flags wieder zurück.
cin >> resetiosflags(ios::skipws);
ws Vorangestellte Whitespaces werden für die nachfolgende
Eingabe überlesen, falls das Flag skipws gelöscht wurde.
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.1 Ein-/Ausgabe über Streams

#include <iostream>
 Formatierte #include <iomanip>
using namespace std;
Eingabe
void main(void)
– Beispiel {
• Ausgabe? char buchstabe1, buchstabe2, buchstabe3;
char string[5];
int zahl;
cout << "Geben Sie drei Buchstaben ein:\n";
cin >> buchstabe1 >> buchstabe2 >> buchstabe3;
cout << "Die Eingabe war: "
<< buchstabe1 << ", "
<< buchstabe2 << ", "
<< buchstabe3 << endl;
cout << "\nGeben Sie eine Hex-Zahl ein:\n";
cin >> hex >> zahl;
cout << "Die Eingabe war: " << zahl << endl;
cout << "\nGeben Sie einen String ein: \n";
cin >> setw(sizeof(string)) >> string;
cout << "Die Eingabe war: " << string << endl;
}
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.1 Ein-/Ausgabe über Streams

 Formatierte Eingabe - Weiteres Beispiel


#include <iostream>
#include <iomanip>
using namespace std;
void main(void)
{
char cFeld[20];
// fuehrende Leerzeichen nicht ignorieren
cin >> resetiosflags(ios::skipws);
//Eingabe auf 19 Zeichen beschraenken
cin >> setw(sizeof(cFeld));
cout << "Texteingabe ohne vorangestellte Leerzeichen: " << endl;
cin >> cFeld; // Leerzeichen verhindern das Einlesen
cout << cFeld << endl;
cout << "Texteingabe mit vorangestellten Leerzeichen: " << endl;
cin >> ws >> cFeld; // Leerzeichen werden ueberlesen
cout << cFeld << endl;
cin >> setiosflags(ios::skipws); // Standard wieder herstellen
}
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.1 Ein-/Ausgabe über Streams

 Weitere Eingabefunktionen - get


Methode: int get(); <iostream>
Wirkung: Entnimmt das nächste Zeichen (oder EOF).

Methode: istream& get(char&); <iostream>


Wirkung: Entnimmt ein Zeichen und überträgt es in die vorgegebene Variable.

Methode: istream& get(char*, int len, char='\n'); <iostream>


Wirkung: Entnimmt solange Zeichen und speichert sie über den vorgegebenen
Parameter (char *) ab, bis sie auf ein Begrenzungszeichen (dritter Para-
meter) oder auf das Dateiende-Zeichen (EOF) stößt, oder aber bis
(len - 1) Bytes gelesen worden sind. Dabei wird stets ein abschlies-
sendes Nullzeichen in den String geschrieben. Das Begrenzungszeichen
wird nicht aus dem Eingabe-Stream entnommen. Die Funktion versagt
nur dann, wenn kein Zeichen aus dem Stream entnommen wurde.

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.1 Ein-/Ausgabe über Streams

 Weitere Eingabefunktionen
– „Nur-Lesen“ eines Zeichens
Methode: int peek(); <iostream>
Wirkung: Liefert das nächste Zeichen zurück, entnimmt es aber nicht.

– Zeilenweises Lesen
Methode: istream& getline(char*, int len, char='\n'); <iostream>
Wirkung: Die Elementfunktion getline entnimmt solange Zeichen und speichert
sie über den vorgegebenen Parameter (char *) ab, bis sie auf ein
Begrenzungszeichen (dritter Parameter) oder auf das Dateiende-Zeichen
(EOF) stößt, oder aber bis (len - 1) Bytes gelesen worden sind. Dabei
wird stets ein abschließendes Nullzeichen in den String geschrieben. Das
Begrenzungszeichen wird aus dem Eingabe-Stream entnommen aber
nicht gespeichert.

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.1 Ein-/Ausgabe über Streams

 Weitere Eingabefunktionen
– Blockweises Lesen
Methode: istream& read( char*, int n); <iostream>
Wirkung: Die Elementfunktion read entnimmt maximal n Zeichen aus dem Einga-
bestream. Stößt sie auf das Dateiende-Zeichen (EOF), wird der Lesevor-
gang abgebrochen.
(Sie wird auch für das blockweise Lesen aus Binärdateien verwendet.)

– Überlesen einer Eingabefolge


Methode: istream& ignore(int n=1, int delim=EOF); <iostream>
Wirkung: Die Elementfunktion ignore bewirkt, dass bis zu n Zeichen des Eingabe-
Streams übersprungen werden. Beim Erreichen des Begrenzerzeichens
stoppt die Funktion. Das Begrenzerzeichen wird aus dem Eingabe-
Stream entnommen.

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.1 Ein-/Ausgabe über Streams


#include <iostream>  Weitere Eingabefunktionen
Weitere Eingabefunktionen
#include <iomanip>
using – Blockweises
namespace std; Lesen– Beispiel
void main(void)
{
int zahl;
cout << "Zahleneingabe: ";
cin >> zahl;
cout << zahl << " * " << zahl << " = " << zahl*zahl << endl;
cout << "weiter mit beliebiger Taste >";
cin.get(); // auf Tastendruck warten - funktioniert das ?
cout << "\n\nZahleneingabe: ";
cin– Überlesen
>> zahl; einer Eingabefolge
cout << zahl << " * " << zahl << " = " << zahl*zahl << endl;
cin.ignore(9999,'\n');
cout << "Ende mit beliebiger Taste > ";
cin.get(); // auf Tastendruck warten - funktioniert's diesmal?
cout << "und tschuess!!";
cin.peek(); // probieren Sie mal
}
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.1 Ein-/Ausgabe über Streams

 Stream-Status
– Alle Streamobjekte (cin, cout, ...) besitzen ein
Statusfeld
• Dort wird in Form von Flags abgespeichert, ob ein Objekt
weiterhin einsetzbar ist oder nicht
• Die Abfrage der Flags kann über Elementfunktionen und
vordefinierte Konstanten geschehen
Flag/Konstante Bedeutung
ios::goodbit Alles i.O., kein anderes Flag gesetzt
ios::eofbit End of File erreicht
ios::failbit Letzter Vorgang nicht korrekt abgeschlossen
(z.B. int soll eingelesen werden, Buchstabe
steht im Streampuffer)
ios::badbit Fataler Fehler, Zustand nicht definiert
(z.B. Positionieren des Dateizeigers vor dem
Dateianfang)
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.1 Ein-/Ausgabe über Streams

 Stream-Status
– Methoden zur Abfrage
Abfragefunktion Bedeutung
good() true, wenn alles i.O. ist (goodbit gesetzt)
eof() true bei End of File (eofbit gesetzt)
fail() true bei Fehler (failbit oder badbit gesetzt)
bad() true bei fatalem Fehler (badbit gesetzt)
• Beispiel
int wert;

cin >> wert;

if (!cin.good()) cout << "Fehler beim Einlesen !!";

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.1 Ein-/Ausgabe über Streams

 Stream-Status
– Im Fehlerfall (failbit, badbit) blockiert ein
E/A-Objekt
• Weitere Operationen sind erst möglich, wenn die Fehler-
flags zurückgesetzt werden
• Funktionen zum Lesen und (Rück)Setzen der Fehlerflags
Funktion Bedeutung
rdstate() Liefert die Fehlerflags
• Beispiel
setstate() Setzt zusätzliche Flags
int wert;
clear() Löscht und setzt einzelne Flags
cin >> wert;
• Beispiel
if (!cin.good())
{
cout << "Fehler beim Einlesen !!";
cin.clear(); // clear ohne Parameter loescht alle Fehlerflags
cin.clear(cin.rdstate()&~ios::failbit); //nur failbit loeschen
}
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.1 Ein-/Ausgabe über Streams

 Stream-Status
– Bewertung des Zustandes auch über zwei vor-
definierte Statuskurzabfragen möglich
Funktion Bedeutung
operator void*() Liefert, ob Stream in keinem Fehlerzustand ist
(entspricht !fail())
operator!() Liefert, ob Stream in einem Fehlerzustand ist
(entspricht fail())

– Anmerkung
• Der neue Standard sieht vor, dass Fehler sog. Ausnah-
men (exceptions, s. Kap. 10) auslösen können
• Die Defaulteinstellung ist jedoch, dass keine Ausnahmen
geworfen werden

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.1 Ein-/Ausgabe über Streams

 Stream-Status
– Beispiel zu Statuskurzabfragen
int wert;

cin >> wert;

// operator !
if (!cin) // if (!(cin >> wert)) ... auch moeglich
{
// Einlesen schlug fehl !!
}

// operator void* (Typumwandlung)


if (cin) // if (cin >> wert) ... auch moeglich
{
// Einlesen hat geklappt !!
}

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.2 Erzwungene Typkonversion

 Erzwungene Typkonversion (Teil 1)


– Cast-Operator
• Erzwungene bzw. explizite Typkonversion in C und C++
TypA a;
TypB b;
...
a = (TypA)b; // cast-Operator
• Alternative (funktionale) Schreibweise in C++
a = TypA(b);
– Sichtweise der Objektorientierung: Ein (meist neues) Ob-
jekt wird temporär aus einem anderen erzeugt (Konstruk-
tor, s. Abschnitt 5.2)
– Die bei der funktionalen Schreibweise verwendeten Klam-
mern haben höhere eine Priorität als die Klammern des
cast-Operators.
 Ist b ein Ausdruck, wird ein Klammerpaar eingespart
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.2 Erzwungene Typkonversion

 Erzwungene Typkonversion (Teil 1)


– Anmerkungen
• Typkontrolle durch den Compiler wird umgangen
• In C++ existieren noch weitere „sichere“ Konvertierungs-
operatoren (im Zusammenhang mit Klassen, s. Kap. 4)
• Eine „Typkonvertierung“ kann auch mit einem leeren
Ausdruck erfolgen
void main()
{
int wert = int();
...
}

– wert wird wie eine globale Variable mit dem Wert 0 initiali-
siert

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.3 Dynamische Speicherverwaltung mit new und delete

 Dynamische Speicherverwaltung
– Alternativen der Speicherverwaltung
• Bibliotheksfunktionen: malloc(), calloc(), free()
• Operatoren: new, delete
Methode: new <iostream>
Aufruf: Typ* pObjekt;
pObjekt = new Typ;
pObjekt = new(Typ);
pObjekt = new Typ(Initialisierungsliste);
pObjekt new Typ[Anzahl];
void= main()
Wirkung: • Reserviert
{ Speicherplatz für ein Objekt
• Berechnet int wert = int();
typspezifisch die Größe des zu reservierenden Speichers
• Initialisiert
... das Objekt ggf. - Initialisierungsliste (bzw. Konstruktor; bei
Arrays wird} der Standardkonstruktor für jede Komponente aufgerufen)
• Gibt einen typisierten Zeiger auf den allokierten Speicherplatz zurück
(NULL bzw. 0, falls kein Speicher reserviert werden konnte  Ergebnis
überprüfen !)
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.3 Dynamische Speicherverwaltung mit new und delete

 Speicherverwaltung mit new und delete


– Beispiel zur Speicheranforderung
const int N = 20, M = 20;

char *pA = new char('1');


int *pB = new int(2);

int *zahlArr = new int[N];

// nur die 1. Dimension kann variabel sein


void main()
int (*pMat)[20] = new int[N][20];
{
int wert = int();
// beide Dimensionen sind variabel
...
double **ppMat = new double*[N]; // Feld von Zeigern auf double
}
for (int z = 0; z < N; z++)
ppMat[z] = new double[M]; // Feld von double

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.3 Dynamische Speicherverwaltung mit new und delete

 Speicherverwaltung mit new und delete


– Fehlerbehandlung - Alternativen
• Lokale Fehlerbehandlung, falls new einen NULL-Zeiger
liefert
if (pObjekt == NULL /* oder 0 */)
{
cout << "Kein Speicher mehr verfuegbar!!";
exit(1);
}

• Globale Fehlerbehandlung über new-Handler


– Eigene Fehlerbehandlungsroutine kann über die Funktion
set_new_handler aktiviert werden
• Ausnahmebehandlung bei Einsatz eines überladenen
new-Operators (Standard C++ Library)
– Bei unzureichendem Speicher wird die Ausnahme
bad_alloc ausgeworfen
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.3 Dynamische Speicherverwaltung mit new und delete

 Speicherverwaltung mit new und delete


– Globale Fehlerbehandlung über new-Handler
• Beispiel - Visual C++ (Funktion hier mit „_” am Anfang)
#include <new.h>
...
// Definition eines eigenen new-Handlers
int MyNewHandler(size_t size)
{
cout << "Kein Speicher verfuegbar!!" << endl;
exit(1);
}
...
// Registrierung des new-Handlers
_set_new_handler(MyNewHandler);
...

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

3.3 Dynamische Speicherverwaltung mit new und delete

 Speicherverwaltung mit new und delete


– Speicherfreigabe
• Der mit new reservierte Speicherbereich bleibt reserviert,
bis das Programm normal beendet oder bis er wieder mit
delete freigegeben wird
Methode: delete <iostream>
Aufruf: delete pObjekt;
delete [] pObjekt;
Wirkung: • Ruft den Destruktor (s. Kap. x) für das referenzierte Objekt auf
• Gibt den Speicher auf den pObjekt zeigt wieder frei
• [] ist für ein- und mehrdimensionale Felder zu verwenden
• Darf nur auf Objekte angewendet werden, die mit new erzeugt wurden
• Darf ohne Konsequenzen auf NULL-Zeiger angewendet werden

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


3.3 Dynamische Speicherverwaltung mit new und delete

 Speicherverwaltung mit new und delete


– Speicherfreigabe
• Beispiel Hier ist die Reihenfolge
auf jeden Fall zu beachten
for (int z = N-1; z >= 0; z--) delete [] ppdMat[z];
delete [] ppdMat;

delete [] pMat; // Freigabe des zweidimensionalen Arrays


delete [] zahlArr; // Freigabe des eindimensionalen Arrays

delete pB;
delete pA;

• Objekte sollten in umgekehrter Reihenfolge ihrer Anfor-


Realisierung
einer derung wieder freigegeben werden
Blockstruktur – Dies hilft, logische Fehler zu vermeiden und
– erleichtert i.d.R. die Speicherverwaltung
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

Übersicht

4. Klassen und Objekte


4.1 Allgemeines
4.2 Definition von Klassen und Objekten
4.3 Zugriffskontrolle
4.4 Memberfunktionen
4.5 Der this-Zeiger
4.6 Konstante Memberfunktionen
4.7 Statische Datenelemente und Memberfunktionen
4.8 friend-Funktionen und -Klassen

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.1 Klassen und Objekte - Allgemeines

 Klassen und Objekte


– Terminologie (S. Vorl.teil „Grundlagen der Programmierung“)
• Eine Klasse ist ein benutzerdefinierter Datentyp, der
ein abstraktes Objekt beschreibt und sowohl Daten als
auch Funktionen enthalten kann
• Ein auf Basis der Klassenbeschreibung angelegtes
Objekt wird als Instanz der Klasse bezeichnet
– Termini von C++ und Objektorientierung ge-
genübergestellt
• Datenelement  Attribut
• Elementfunktion  Methode,
Memberfunktion
• Aufruf einer Elementfunktion  Botschaft an das Objekt
senden

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.2 Definition von Klassen und Objekten

 Definition von Klassen und Objekten


– Drei Arten von Klassen in C++
• struct, class
• union (keine Vererbung)
– Klassendefinition
class KlassenName
{
Typ VarName;
...
RückgabeTyp FktName(...) { ... }
...
};
• Beginn mit einem der drei angegebenen
Schlüsselwörter class Katz {float schnurrFaktor;
• Beispiel int schnurr(); …};
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.2 Definition von Klassen und Objekten

 Definition von Klassen und Objekten


– Klassendefinition - Weitere Anmerkungen
• I.d.R. wird class zur Klassendefinition verwendet
• KlassenName bezeichnet den neuen Objekttyp
• Die Vereinbarung von Datenelementen und Element-
funktionen einer Klasse wird in { ... }; eingeschlos-
sen (Reihenfolge beliebig)
• Attributnamen müssen sich von Funktionsnamen unter-
scheiden
• Eine Klassendefinition öffnet einen neuen Gültigkeitsbe-
reich, d.h. in verschiedenen Klassen können gleiche Be-
zeichner verwendet werden
• Die Klassendefinition muss mit ; abgeschlossen werden
• Memberfunktionen haben Zugriff auf alle Klassenele-
mente (implizit über den this-Zeiger)
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.2 Definition von Klassen und Objekten

 Definition von Klassen und Objekten


– Klassendefinition - Weitere Anmerkungen
• Eine Klasse ist nach Abschluss des Klassenkopfes de-
klariert, der KlassenName kann dann schon innerhalb der
Klassendefinition eingesetzt werden
– Z.B. Zeiger auf Klassenobjekte
– Beispiel class A { int x; A* pA; };

• Zirkuläre Abhängigkeiten erfordern sog. Vorwärtsdekla-


rationen
class A ; // Vorwaertsdeklaration
– Beispiel class B { int x; A* pA; };
class A { int y; B* pB; };

– Objektdefinition
KlassenName ObjektName;
• Erzeugt eine Instanz der Klasse mit Namen ObjektName
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.2 Definition von Klassen und Objekten

 Klassendefinition - Beispiel
#include <iostream> cratio1.h
using namespace std;
// Klassendefinition
struct CRatio
{
// Elementfunktionen
void Eingabe()
{
do
{
cin >> zae >> nen;
if (nen==0) cerr << "\n Nenner==0!\n Eingabe wiederholen: ";
} while(nen == 0);
}
void Ausgabe() { cout << zae << "/" << nen << endl; }
// Datenelemente
int zae, nen; // Zaehler, Nenner
};
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.2 Definition von Klassen und Objekten

 Objektdefinition/-verwendung - Beispiel
#include "cratio1.h"
#include <iostream>
using namespace std;
void main()
{
CRatio ersteZahl, zweiteZahl; // Objektdefinition
CRatio *pCRatio = &ersteZahl;
cout << "ErsteZahl = ";
ersteZahl.Eingabe(); // Methodenaufruf
zweiteZahl.zae = 5; // ebenfalls moeglich
zweiteZahl.nen = 0; // Problem !!!
cout << "ErsteZahl = ";
pCRatio->Ausgabe(); // Methodenaufruf ueber Zeiger
(*pCRatio).Ausgabe(); // Alternative
cout << "ZweiteZahl = ";
zweiteZahl.Ausgabe(); // oder wie gehabt...
}
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.2 Definition von Klassen und Objekten

 Beispiel mit besserer Fehlerbehandlung


#include <iostream>
using namespace std; cratio1m.h
// Klassendefinition
struct CRatio
{ "Zahl = "
// Elementfunktionen
void Eingabe(const char *prompt)
{
zae = nen = 0;
do
{
cout << prompt;
cin >> zae >> nen;
if (!cin) nen = 0;
if (nen==0) cerr << "Eingabefehler!\n";
cin.clear();
cin.ignore(9999, '\n');
} while(nen == 0);
}
void Ausgabe() { cout << zae << "/" << nen << endl; }
// Datenelemente
OTHint zae, nen;
Amberg-Weiden // Zaehler, Nenner
};
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.2 Definition von Klassen und Objekten

 Klassen und Objekte - Anmerkungen


– Zugriff auf Elemente
• Über den Punktoperator . oder den Pfeiloperator ->
– Eine Klasse ist ein neuer Datentyp
• Zeiger können auf Klassenobjekte (Instanzen) zeigen
• Speicher kann dynamisch für Klassenobjekte reserviert
werden (new, delete)
• Es können Arrays von Klassenobjekten gebildet werden
• Klassenobjekte können Teil einer anderen Klasse sein
• Klassenobjekte können an Funktionen übergeben wer-
den
• Klassenobjekte können von Funktionen zurückgegeben
werden

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.3 Zugriffskontrolle

 Zugriffskontrolle
– C++ - Klassen unterstützen ADT durch die
Möglichkeit der Zugriffsbeschränkung
– Schutzbereiche
private: Alle Komponenten sind nur innerhalb der Klasse sichtbar,
d.h. private Komponenten können nur von Komponenten
der eigenen Klasse und von „Freunden“ referenziert werden.
Attribute sind in der Regel private.
public: Auf Komponenten nach public: kann ungehindert auch
von außen zugegriffen werden.
Schnittstellenfunktionen sind i.a. public.
protected: protected wirkt nach außen wie private, jedoch ist der
Zugriff für Komponenten abgeleiteter Klassen möglich.
• Kurz
– public: Von jedem verwendbar
– private: Nur von eigenen Methoden zugreifbar
– protected: Von eigenen Methoden und denen abgelei-
teter Klassen zugreifbar
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.3 Zugriffskontrolle

 Zugriffskontrolle
– Standardmäßig sind die Komponenten bei
Klassendefinition mit
• class im Schutzbereich private und bei
• struct und union im Bereich public
– Anmerkungen
• Von den Voreinstellungen sollte kein Gebrauch gemacht
werden; besser ist es, den Zugriff explizit anzugeben
• In der Regel werden public-Komponenten immer an
den Anfang der Definition gestellt, da sie für den Benut-
zer der Klasse wichtig sind
• Es dürfen auch mehrere Abschnitte mit public:,
private: bzw. protected: vorkommen

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.3 Zugriffskontrolle

 Zugriffskontrolle
– Anmerkungen zu class als Klasse
• Der Schutz ist definitionsgemäß „sicher“ eingestellt
• Sollte nach Möglichkeit verwendet werden
– Anmerkungen zu union als Klasse
• Eine union darf nicht enthalten
– Statische Member
– Klassenobjekte, deren Klassendefinition einen Konstruktor,
einen Destruktor oder einen selbstdefinierten Zuweisungs-
operator enthält
• Eine union darf keine Basisklassen besitzen und auch
selbst nicht als Basisklasse verwendet werden

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.3 Zugriffskontrolle

 Zugriffskontrolle - Modifiziertes Beispiel


#include <iostream> cratio2.h
// Klassendefinition
class CRatio
{
public:
// Elementfunktionen
void Eingabe() { ... }
void Ausgabe() { ... }
#include "cratio2.h"
private:
#include <iostream>
// Datenelemente
int zae, nen; void main()
}; {
CRatio ersteZahl, zweiteZahl;
...
ersteZahl.Eingabe(); // Methodenaufruf i.O.
zweiteZahl.zae = 5; // Fehlermeldung !!!
...
}
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.4 Memberfunktionen

 Memberfunktionen
– Einteilung in vier Kategorien
• Verwaltungsfunktionen - public
– Funktionen zur Initialisierung, Speicherverwaltung oder
Konvertierungen, etc.
– Im allgemeinen implizit aufgerufen (Vertreter: Konstrukto-
ren, Destruktoren)
• Ausführungsfunktionen - public
– Stellen den eigentlichen Dienst zur Verfügung, für den die
Klasse entworfen wurde
• Hilfsfunktionen - private
– Dienen zur Strukturierung und Unterstützung anderer
Memberfunktionen
• Zugriffsfunktionen - public
– Ermöglichen den Zugriff (r/w) auf private Memberdaten
– Die Definition von Memberfunktionen kann innerhalb oder
außerhalb der Klassendefinition stattfinden
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.4 Memberfunktionen

 Memberfunktionen
– Definition innerhalb oder außerhalb einer
Klasse möglich
– Definition innerhalb einer Klasse
• Implizite inline - Definition
• Alle Elementfunktionen,
die innerhalb einer #include <iostream> cratio3.h
Klasse vollständig // Klassendefinition
definiert werden, sind class CRatio
{
automatisch inline
public:
• Beispiel // Elementfunktionen - implizit inline
void Init() {zae=0; nen=1;}
void Eingabe() { ... }
void Ausgabe() { ... }
...
};
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.4 Memberfunktionen

 Memberfunktionen
– Definition außerhalb einer Klasse
• In der Klassendefinition werden nur die Prototypen der
Elementfunktionen angegeben
• Über den binären scope resolution - Operator :: wird
außerhalb bei der Definition festgelegt, zu welcher Klas-
se die Elementfunktion gehört
KlassenName::ElementBezeichner
– Entspricht der Qualifizierung bei Namensräumen
• Ermöglicht eine Trennung von Schnittstellendeklaration
und Implementierung im Sinne der ADTen
– Die genaue Implementierung eines ADTen ist irrelevant
und sollte nicht vom Anwender in einer bestimmten Form
vorausgesetzt werden
• Bei externen Definitionen muss inline explizit ange-
geben werden (falls so gewollt)
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.4 Memberfunktionen

 Memberfunktionen außerhalb definiert - Bsp


#include <iostream> cratio4.h
class CRatio
{
public:
// Prototypen der Elementfunktionen
void Init();
void Eingabe();
void Ausgabe();
private:
// Datenelemente
int zae, nen; // Zaehler, Nenner inline void CRatio::Eingabe()
}; {
...
// Funktionsdefinitionen extern inline }
inline void CRatio::Init()
{ inline void CRatio::Ausgabe()
zae = 0; {
nen = 1; ...
} }

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.4 Memberfunktionen

 Trennung: Schnittstelle - Implementierung


– Klassendefinition und damit Schnittstellenbe-
schreibung erfolgt in einer Informationsdatei
• Endung: *.h oder *.hpp
• Sollte auch alle explizit definierten inline-Funktionen
enthalten
• Mit einer Klammerung durch #ifndef ... #endif kann
eine Mehrfachdefinition beim Übersetzungsvorgang ver-
hindert werden
– Implementierung der Elementfunktionen
erfolgt in der zugehörigen Implementierungs-
datei
• Endung: *.cpp, unter UNIX *.C oder *.cc

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.4 Memberfunktionen

 Schnittstelle
– Beispiel mit teilweiser Trennung
// Definition der Klasse CRatio cratio5.h
#ifndef CRATIO5_H
#define CRATIO5_H
#include <iostream>
class CRatio
{
public:
// Prototypen der Elementfunktionen
void Init() {zae = 0; nen = 1;} inline void CRatio::Ausgabe()
void Eingabe(); {
void Ausgabe(); std::cout << zae << "/"
private: << nen << std::endl;
// Datenelemente }
int zae, nen; //Zaehler, Nenner
}; #endif

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.4 Memberfunktionen

 Implementierung und Anwendung


– Beispiel mit teilweiser Trennung
// Implementierung der Methoden von CRatio cratio5.cpp
#include <iostream>
#include "cratio5.h"
using namespace std; // Anwendung tstcrat.cpp
void CRatio::Eingabe()
{ #include "cratio5.h"
do
{ void main()
cin >> zae >> nen; {
if (nen == 0) CRatio eineZahl;
{ ...
cerr << "\n Nenner==0! \n" eineZahl.Init();
<< " Eingabe wiederholen: "; ...
} eineZahl.Ausgabe();
} while(nen == 0); ...
} }

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.4 Memberfunktionen

 (Externe) inline-Memberfunktionen
– Vor-/Nachteile von inline-Memberfunktionen
• Vorteile
– Geschwindigkeitssteigerung
– Eine externe inline-Definition kann leichter rückgängig
gemacht werden
• Nachteile
– Größerer Codeumfang
– Implementierung ist nach außen hin sichtbar
– Bei impliziten (also nicht externen) inline-Funktionen
wird die Schnittstellenbeschreibung durch eingestreuten
Implementierungs-Code schwerer lesbar

 Nur sehr kurze Funktionen inline definieren!

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.4 Memberfunktionen

 (Externe) inline-Memberfunktionen
– Ort der Deklaration
• Sollten immer in der Schnittstellendatei deklariert und
definiert werden
• Werden inline-Deklarationen in die Implementierungs-
datei verlagert, so sind sie nur dort bekannt und damit
nur dort wirksam!
 Anwendung kennt nur die Schnittstelle durch das Einbin-
den der Informationsdatei, die keinen Hinweis auf inline
enthält
 Funktion wird nicht eingefügt sondern aufgerufen
 Der Linker kann diesen Aufruf jedoch nicht herstellen, da
für eine inline-Funktion keine Referenz vorliegen kann
 Fehlermeldung durch den Linker!!

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.5 Der this-Zeiger

 Der this-Zeiger
– Jeder Elementfunktion wird implizit als erstes
Argument ein Zeiger auf das Klassenobjekt
übergeben
• Über diesen Verweis wird (ebenfalls implizit) auf die
Komponenten des Objekts zugegriffen
• Beispiel
CRatio eineZahl;
... wird implizit
eineZahl.Eingabe(); Eingabe(&eineZahl);
ersetzt durch
– Der „interne“ Prototyp lautet void Eingabe(CRatio * const this);

– Die Definition KlassenName * const this stellt sicher, dass der


Zeiger this nicht verändert werden kann und immer auf das einmal zu-
gewiesene Klassenobjekt zeigt
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.5 Der this-Zeiger

 Der this-Zeiger
– Jede Elementfunktion darf den this-Zeiger
auch explizit verwenden
– Einsatz von this, wenn
• eine Elementfunktion
– das aktuelle Objekt (Wert),
– eine Referenz (return *this;) oder
– einen Zeiger (return this;) auf das aktuelle Objekt
zurückgeben soll oder
• die Elementfunktion eine weitere Funktion aufrufen soll,
an die das aktuelle Objekt oder ein Zeiger darauf überge-
ben werden muss oder
• Komponenten des Klassenobjekts durch lokale Größen
verdeckt sind (this->Komponente)

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.5 Der this-Zeiger

 Der this-Zeiger - Beispiel


//Definition der Klasse CRatio cratio6.h
#ifndef CRATIO_H
#define CRATIO_H
class CRatio
{ Überladen von
public: Memberfunktionen
// Prototypen der Elementfunktionen
void Init() {zae = 0; nen = 1;}
void Init(int Zaehler, int Nenner=1) {zae = Zaehler, nen = Nenner;}
void Eingabe();
void Ausgabe();
CRatio& PlusGleich(const CRatio& rOb);
const CRatio Minus (const CRatio& rOb);
private:
// Datenelemente
int zae, nen; //Zaehler, Nenner
};
#endif
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.5 Der this-Zeiger

const CRatio CRatio::Minus(const CRatio& rOb)


// Wertrueckgabe

CRatio& CRatio::PlusGleich(const CRatio&rOb)


// Rueckgabe einer Referenz

void CRatio::Ausgabe() {...}


void CRatio::Eingabe() {...}

#include <iostream>
#include "cratio .h"

// Implementierung der Methoden von Cratio


 Der this-Zeiger
}

{
return(help);

help.nen = nen * rOb.nen;


help.zae = zae * rOb.nen - rOb.zae * nen;
// veraendert
// Objekt (*this) wird diesmal nicht

CRatio help;

return(*this);

this->nen = this->nen * rOb.nen;


// notwendig
// Zugriff über this moeglich, aber nicht
zae = zae * rOb.nen + rOb.zae * nen;
// Objekt wird veraendert
6

cratio .cpp
6

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.5 Der this-Zeiger

#include "cratio6.h” Anwendung



#include <iostream>
Der this-Zeiger
using namespace std;
void main()
{
CRatio bruch1, bruch2, bruch3, bruch4;

bruch1.Init(1, 2);
bruch2.Init(1, 2);
bruch3.Init();
bruch3 = bruch1.PlusGleich(bruch2);
cout << "Bruch3 = Bruch1.PlusGleich(Bruch2) = " << endl;
bruch3.Ausgabe();
bruch4 = bruch1.Minus(bruch2);
cout << "\n\nBruch4 = bruch1.Minus(Bruch2) = " << endl;
bruch4.Ausgabe();
bruch4 = bruch1.PlusGleich(bruch2).Minus(bruch3);
cout<<"\n\nBruch4 = Bruch1.PlusGleich(Bruch2).Minus(Bruch3)"<<endl;
bruch4.Ausgabe();
}
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.6 Konstante Memberfunktionen

 Konstante Memberfunktionen
– Spezifikation: Zusatz const hinter dem Funk-
tionskopf einer Elementfunktion
• Objektkomponenten class CRatio
{
können innerhalb der public:
Funktion nicht verän- void Init() {zae = 0; nen = 1;}
dert werden void Ausgabe() const; //Deklaration
• Nicht const-spezifi- ...

zierte Elementfunktio- private:


int zae, nen; //Zaehler, Nenner
nen können nicht auf- };
gerufen werden
void CRatio::Ausgabe() const //Definition
• Beispiel {
// zae und nen koennen nicht veraendert
// werden
cout << zae << "/" << nen << endl;
}
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.6 Konstante Memberfunktionen

 Konstante Memberfunktionen
– Anmerkungen
• Der Zusatz const ändert den Typ des implizit
übergebenen this-Zeigers auf
const KlassenName * const this
– this ist jetzt ein konstanter Zeiger auf ein konstantes
Objekt!
• Ausnahme
– Werden Datenelemente explizit mit mutable gekenn-
zeichnet, dann dürfen sie von const-Elementfunktionen
geändert werden
...
private:
mutable int zae; // zae koennte in Ausgabe()
// geaendert werden,
int nen; // nen nicht

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.6 Konstante Memberfunktionen

 Konstante Memberfunktionen
– Anmerkungen
• Für const - Klassenobjekte können nur const-Mem-
berfunktionen aufgerufen werden!
– Für nicht const-Klassenobjekte können beide Arten von
Memberfunktionen aufgerufen werden
– Beispiel
const CRatio zahl1;
CRatio zahl2;
zahl1.Eingabe(); // nicht moeglich !!
zahl1.Ausgabe(); // OK
zahl2.Ausgabe(); // OK

• Grundsätzlich sollten alle Methoden einer Klasse, die


keine Attribute ändern, als const- Elementfunktionen
implementiert werden
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.7 Statische Datenelemente und Memberfunktionen

 Klassenspezifische Daten und Funktionen


– Bedeutung
• Klassen sind einerseits Beschreibungen für den Aufbau
von Objekten
• Sie können aber auch selber über Objekte verfügen
• Statische Komponenten existieren nur einmal für alle
Klassenobjekte
– Sie sind nicht an die Klassenobjekte gebunden
– Sie sind an die Klasse gebunden
– Sie sind nach der Klassendefinition verfügbar, auch wenn
noch kein Klassenobjekt existiert
– Syntaktisch
• Deklaration mit dem Schlüsselwort static

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.7 Statische Datenelemente und Memberfunktionen

 Statische Datenelemente
– Deklaration und Definition
• Ein statisches Datenelement wird mit static innerhalb
der Klasse deklariert
• Es muss außerhalb der Klassendeklaration einmal
definiert und ggf. initialisiert werden
– Fehlt diese Initialisierung, so erfolgt automatisch eine Ini-
tialisierung mit 0 vom entsprechenden Typ
– Anwendungen
• Speicherung von Statusinformationen, die alle Objekte
betreffen
• Überwachung bzw. Begrenzung der Anzahl von Instan-
zen
• Wurzel-Zeiger für Listen
• ...
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.7 Statische Datenelemente und Memberfunktionen

 Statische Datenelemente - Beispiel


... cratio7.h
class CRatio
{
public:
...
// Ausgabe als Bruch oder im float-Format
enum Anzeige {Bruch, Gltpkt};
static Anzeige art;
...
};
... cratio7.cpp
... // Initialisierung: Typ Name = Wert; - ohne static!
CRatio::Anzeige CRatio::art = CRatio::Bruch;

inline void CRatio::Ausgabe() const


{
if (art == Bruch) cout << zae << "/" << nen << endl;
else cout << float(zae)/nen << endl;
}
...
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.7 Statische Datenelemente und Memberfunktionen

 Statische Datenelemente - Beispiel


#include "cratio7.h" Anwendung
#include <iostream>
using namespace std;
void main()
{
CRatio bruch1, bruch2;
bruch1.Init(1, 2); bruch2.Init(2, 3);
cout << "Bruch1 = "; bruch1.Ausgabe();
cout << "Bruch2 = "; bruch2.Ausgabe();
bruch1.art = CRatio::Gltpkt; // aendert Art fuer alle Klassenobjekte
cout << "Bruch1 = "; bruch1.Ausgabe();
cout << "Bruch2 = "; bruch2.Ausgabe();
CRatio::art = CRatio::Bruch; // Zugriff ohne Objekt ebenfalls
// moeglich
cout << "Bruch1 = "; bruch1.Ausgabe();
cout << "Bruch2 = "; bruch2.Ausgabe();
}
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.7 Statische Datenelemente und Memberfunktionen

 Statische Datenelemente
– Anmerkungen
• Der Zugriff ohne Objekt über die Klassenbezeichnung ist
für statische public-Komponenten möglich
• Bei der Initialisierung spielt das Zugriffsrecht (private,
protected, public) keine Rolle
• Die Initialisierung darf nur ein einziges Mal stattfinden
– Trennung in Informationsdatei und Implementierungsdatei
notwendig
– Erst ab C++17 ist eine Initialisierung bei der Klassendefini-
tion durch Zusatz von inline möglich, so dass keine Ini-
tialisierung in einer Implementierungsdatei notwendig ist
• static-Komponenten werden durch sizeof() und
new bei der Ermittlung des Speicherplatzes für ein Klas-
senobjekt nicht berücksichtigt

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.7 Statische Datenelemente und Memberfunktionen

 Statische Memberfunktionen
– Allgemeine Anmerkung
• Grundsätzlich existiert von jeder Elementfunktion (sta-
tisch oder nicht) nur ein Exemplar pro Klasse
– Eigenschaften statischer Elementfunktionen
• Sie erhalten keinen this-Pointer auf „normale“ Klassen-
objekte
 Keine Bindung an ein individuelles Klassenobjekt
 Kein Zugriff auf individuelle Objektkomponenten möglich
• Zugriff auf statische Klassenattribute (auch auf private)
• Aufruf von öffentlichen static-Elementfunktionen ohne
Objektbezug über die Klassenbezeichnung möglich
– Verbesserung des vorhergehenden Beispiels
• Information-Hiding durch eine statische Elementfunktion
für den Zugriff auf art
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.7 Statische Datenelemente und Memberfunktionen

 Statische Memberfunktionen - Beispiel


... cratio8.h
class CRatio
{
public:
...
// Ausgabe als Bruch oder im float-Format
enum Anzeige {Bruch, Gltpkt};
static void SetzeArt(Anzeige Typ);

private:
... cratio8.cpp
// Datenelemente // Definition der statischen Elementfunktion
int zae, nen; void CRatio::SetzeArt(Anzeige
// Zaehler, Nenner Typ)
static Anzeige art; {
}; art = Typ;
... // nen = 1; // waere nicht moeglich !
}

// Initialisierung: Typ Name = Wert;


CRatio::Anzeige CRatio::art = CRatio::Bruch;

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.7 Statische Datenelemente und Memberfunktionen

 Statische Memberfunktionen - Beispiel


#include "cratio8.h" Anwendung
#include <iostream>
using namespace std;
void main()
{
CRatio bruch1, bruch2;
bruch1.Init(1, 2);
bruch2.Init(2, 3);
cout << "Bruch1 = ";
bruch1.Ausgabe();
cout << "Bruch2 = ";
bruch2.Ausgabe();
CRatio::SetzeArt(CRatio::Gltpkt); // Aufruf ohne Objektbezug
cout << "Bruch1 = ";
bruch1.Ausgabe();
cout << "Bruch2 = ";
bruch2.Ausgabe();
}
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.8 friend-Funktionen und -Klassen

 friend-Funktionen und -Klassen


– Freunden kann man vertrauen !?
– Bedeutung
• Eine Klasse kann sog. friend-Funktionen oder
friend-Klassen den Zugriff auf private- oder
protected-Komponenten gewähren
• Der Zugriffsschutz sollte nur wenn unbedingt notwendig
(Operator-Überladung, Initialisierung, ...) durch friend-
Deklarierungen unterlaufen werden

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.7 Statische Datenelemente und Memberfunktionen

 friend-Funktionen - Beispiel
class A
{
public:
void KontrolleIstGut() {a = 10; b = 20;}
friend void VertrauenIstBesser(A& rObjekt); // keine Memberfkt.
int a;
private: // externe Funktionen:
int b; void VertrauenIstBesser(A& rObjekt)
}; {
rObjekt.a = 0; // OK, da public
rObjekt.b = 1; // Zugriff auf private-Komponente !
}

void KontrolleIstBesser(A& rObjekt) // kein friend !


{
rObjekt.a = 0; // OK, da public
// rObjekt.b = 1; // nicht moeglich !!
}

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.8 friend-Funktionen und -Klassen

 friend-Funktionen und -Klassen


– Anmerkungen
• Der friend-Funktion steht kein this-Zeiger zur
Verfügung
– Die Objektreferenz muss explizit übergeben werden
• Nur die Deklaration innerhalb der Klasse erhält das
Schlüsselwort friend
• Der Zugriffsschutz an der Stelle der Deklaration
(private, protected oder public) spielt für friend-
Komponenten keine Rolle
– Andere Klassen(-Funktionen) als friends
• Auch einzelne Elementfunktionen anderer Klassen kön-
nen friends sein
• Alle Elementfunktionen einer Klasse können friend-
Funktionen einer anderen Klasse sein = friend-Klasse
OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022


4.8 friend-Funktionen und -Klassen

 friends durch andere Klassen


– Beispiel: friend-Funktionen in anderen Klassen
class A
{
...
friend void B::Fkt1(A* pObjekt);
}; void B::Fkt1(A* pObjekt)
class B {
{ // Zugriff auf oeffentliche und
... // geschuetzte Komponenten des durch
void Fkt1(A* pObjekt); // pObjekt referenzierten Objektes
void Fkt2(A* pObjekt); }
};
void B::Fkt2(A* pObjekt)
{
// Zugriff nur auf oeffentliche
// Komponenten des durch pObjekt
// referenzierten Objektes
}

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik
KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

4.8 friend-Funktionen und -Klassen

 friends durch andere Klassen


– Beispiel: Andere Klasse (vollständig) als Freund
class A
{
...
friend class B; // alle Funktionen von B
... // sind friends von A!
};

– Weitere Anmerkungen
• friend-Beziehungen zwischen Klassen können auch
wechselseitig sein
• Vorsicht! Diese Form der Öffnung nach außen hin ver-
letzt das Prinzip des Information Hiding stark

OTH Amberg-Weiden
Programmierung II / Einführung in C++ Josef Pösl
Informatik

KOPIE FÜR 6DF1.OTH-AW.DE (MOHAMMAD FADAVI), ERSTELLT: 12.04.2022

Das könnte Ihnen auch gefallen