10.04.2000
Universität Dortmund, Lehrstuhl Informatik [email protected]
EINI IIEinführung in die Informatik
für Naturwissenschaftler und Ingenieure II
Prof. Dr. Gisbert Dittrich
14-2
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Gliederung
Einführung in Klassen• Kapselung von Attributen+Methoden (wie struct)
– Funktion --> Methode– Unterschiede: Voreinstellungen
• Erweiterung der Möglichkeiten von struct:– Überladen von Methoden– Konstruktor/Destruktor
Allgemeine Regeln
(durchgeführt am Beispiel: Punkt)
14-3
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Ziele von Klassen
• Kapselung von Attributen+Methoden (wie struct)• Erweiterte Möglichkeiten gegenüber struct
– Überladen von Methoden– Konstruktoren– Destruktoren
• Effiziente Wiederverwendbarkeit– Vererbung --> Kap. 15 ff– Virtuelle Methoden--> 16 ff
14-4
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
class (vs. struct)
• Schlüsselwort: class• Klassen sind analog zu structs
– Abweichungen von der Voreinstellung (default)
sind explizit vorzunehmen.
• Voreinstellungen
für Komponenten sind in – struct: public– class : private
• Instanzen von Klassen heißen Objekte
14-5
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Beispiel: Punkt
Aufgabe:• Modelliere Punkte in der Ebene (ADT Punkt).• Daten:
– Ein Punkt hat x- und y-Koordinaten
• Operationen:– Setzen und Lesen der Koordinaten– Verschieben eines Punkts– Drucken eines Punkts– Test auf Gleichheit mit einem anderen Punkt
14-6
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Das ist neu - und der springende Punkt
class Punkt {private:
int x, y;public:
void xSetze(int a);void ySetze(int a);int xWert();int yWert();void Druck(char *); void Verschiebe(int, int);bool Gleich(Punkt);
};
verborgen
öffentlichzugänglich
class Punkt {Beispiel: Punkt (Code)
14-7
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
class Punkt
• Die Koordinaten nicht öffentlich zugänglich,• alle anderen Komponenten eines Punkts wohl.• Code für die einzelnen Komponenten:void Punkt::xSetze(int a) { x = a; }
void Punkt::ySetze(int a) { y = a; }
int Punkt::xWert() { return x; }
int Punkt::yWert() { return y; }
14-8
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Realisierung der Methoden
void Punkt::Druck(char * s) {cout << s << "x-Wert: " << x << ", y-Wert: " << y << ";\n";
}
void Punkt::Verschiebe(int dx, int dy) {x = x + dx; y = y + dy;
}
bool Punkt::Gleich(Punkt p) {return (x == p.x && y == p.y ?
true : false);}
14-9
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Ausgabe: p: x-Wert: 4, y-Wert: 7;q: x-Wert: 13, y-Wert: 9;p = q? false p = q? true
int main() {Punkt p, q; p.xSetze(4); p.ySetze(7); p.Druck("p: ");q.xSetze(13); q.ySetze(9); q.Druck("q: ");cout << "p = q? "
<< (p.Gleich(q) ? "true" : "false" << endl;
p.Verschiebe(9, 2); cout << "p = q? " << (p.Gleich(q) ? "true" : "false") << endl;
return 0;}
14-10
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Überladen von Funktionen
• Derselbe Name kann für verschiedene
Versionen einer Funktion verwendet werden.• Beispiel zu Punkt:
– bool Gleich(Punkt); (s.o.)– bool Gleich(Punkt*); neu
Kann Objekte, die auf einen Punkt zeigen (also nicht nur Punkte selbst), auf Gleichheit mit dem vorgegebenen Punkt testen.
• Unterscheidung der verschiedenen Versionen? – Klar: nach der Signatur!
14-11
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
class Punkt {private:
int x, y;public:
void xSetze(int a);void ySetze(int a);int xWert();int yWert();void Druck(char *);
void Verschiebe(int, int); bool Gleich(Punkt); bool Gleich(Punkt*); };
Test auf Gleichheit
Das istder
inter-essierendePunktPunkt
14-12
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Implementierungen: Gleich
bool Punkt::Gleich(Punkt p) {cout << "(verwendete Version: Punkte)\n";return (x == p.x && y == p.y ? true : false);}
bool Punkt::Gleich(Punkt * pStern) {cout << "(verwendete Version:"
<< "Zeiger auf Punkte)\n";return (x == pStern->x &&
y == pStern->y ? true : false);}
14-13
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
int main() {Punkt p, *q = new Punkt;
p.xSetze(4); p.ySetze(7); ...q->xSetze(13); q->ySetze(9); ...cout << "p = q? "
<< (p.Gleich(*q) ? "true" : "false") << endl;
p.Verschiebe(9, 2); cout << "p = q? "
<< (p.Gleich(q) ? "true" : "false") << endl;
return 0;}
Ausgabe: ...p = q? (verwendete Version: Punkte)falsep = q? (verwendete Version: Zeiger auf Punkte)true
14-14
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Überladen einer Methode
• Offensichtlich: • Beim Aufruf ist klar, welche Version gemeint ist.
Dies kann am Typ des aktuellen Parameters
abgelesen werden.
• Der Übersetzer muß diese Arbeit schon leisten können.
• Später bei der Diskussion der Vererbung:• „Polymorphie“, dann Auflösung zur Laufzeit.
14-15
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Konstruktoren
• Aufgabe eines Konstruktors: • Speicherplatz für die Instanzen einer Klasse zur
Verfügung zu stellen.– Zur Erinnerung:
In der Vereinbarung Punkt * p;
wird zunächst nur der Name p bekannt gemacht (als Zeiger auf einen Punkt).
Speicher muß dann explizit mit new allokiert werden.
• Speicherallokation kann um Initialisierung eines Objekts ergänzt werden.
14-16
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Konstruktoren (Forts.)
• Es können auch weitere Operationen innerhalb eines Konstruktors durchgeführt werden, z.B.:
– Benachrichtigung der Umgebung, daß das Objekt jetzt vorhanden ist,– Setzen von lokalen Werten,– Aufrufen von Funktionen oder Methoden,– etc.(was immer notwendig ist).
14-17
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Konstruktoren (Forts.)
• Operationen bei der Erzeugung eines Ob-
jekts werden in Konstruktoren durchgeführt.
• Eigenschaften von Konstruktoren:• die Konstruktoren heißen wie die Klassen,• sie geben keinen Wert zurück,• sie können überladen werden
– Durch Überladung sind verschiedene Arten der Initialisie-rung möglich.
14-18
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Konstruktoren für die Klasse Punkt
class Punkt {private:
int x, y;public:
Punkt();Punkt(int, int);void Druck(char *);
...int yWert();
};
Das sind dieKonstruktoren
14-19
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Implementierung
Punkt::Punkt() {cout << "Damit ist für den Punkt"
<< " Speicher bereitgestellt;"<< " die Werte sind undefiniert."
<< endl;// x = y = 0; ?}
Punkt::Punkt(int x1, int y1) {x = x1; y = y1;
}
14-20
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Anmerkungen
• Der parameterlose Konstruktor Punkt() wird als voreingestellter Konstruktor aufgerufen, wenn ein Objekt vom Typ Punkt vereinbart und kein Konstruktor angegeben wird.
• Der Konstruktor Punkt(x1, y1) initialisiert das Objekt entsprechend.
14-21
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Anmerkungen
• Beispiel:Punkt p;p.xSetze(3); p.ySetze(6);
kann auch so ausgedrückt werden:
Punkt p(3, 6);
• Allgemeine Regel: Bei der Vereinbarung wird derjenige Konstruktor aufgerufen, der auf der Grundlage der mitgegebe-nen Parameter identifiziert werden kann.
14-22
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Anmerkungen
• Zeiger auf Objekte werden wie üblich mit
new allokiert, wobei der entsprechende
Konstruktor aufgerufen wird.• Beispiel:
Punkt * q = new Punkt(13, 9);
Punkt * r = new Punkt();
Punkt * t = new Punkt;– Die letzten beiden Konstruktor-Aufrufe sind gleichwertig.
14-23
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
int main() {Punkt p;
p.xSetze(4); p.ySetze(7); p.Druck("p: ");Punkt * q = new Punkt(13,9);q.Druck("q: ");...}
Ausgabe: Damit ist für den Punkt Speicher bereit-gestellt; die Werte sind undefiniert.p: x-Wert: 4, y-Wert: 7;q: x-Wert: 13, y-Wert: 9;
14-25
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Speicherfreigabe
• Ist z ein Zeiger einTyp * z;
so gibt delete z den Speicherbereich
frei, auf den z zeigt, falls das Objekt über
new erzeugt wurde. • Das ist die genaue Umkehrung von new. • Syntaktisch muß z ein Zeiger sein.
14-26
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Speicherfreigabe
• Anmerkungen:• delete ist nützlich, wenn
– Speicher knapp ist, – bestimmt werden kann, daß das Objekt nicht mehr benötigt wird.
• delete ist gefährlich – bei nachlässiger Verwendung
(einer der Gefahrenpunkte bei C++!)
14-27
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
der Destruktorheißt wie dieKlasse, (mit~ gekenn-
zeichnet), undist parameterlos
der Destruktorheißt wie dieKlasse, (mit~ gekenn-
zeichnet), undist parameterlos
class Punkt {private:
int x, y;public:
Punkt();Punkt(int, int);~Punkt();void Druck(char *);
...int yWert();
};
Destruktor: Syntax
14-28
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Anmerkung
• Der Destruktor (falls vorhanden) wird immer dann aufgerufen, wenn der Speicherplatz für das Objekt freigegeben wird, also auch beim Aufruf von delete..
14-29
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
/* Klasse Punkt; lauffähiger Code, GD 9.4.00, Vorlage EED, EINI II, SS 99*/
#include <iostream.h>int s = 0;class Punkt {
private:int x, y;
public:Punkt();Punkt(int, int);~Punkt();void xSetze(int);void ySetze(int);int xWert();int yWert();};void Verschiebe(int, int); bool Gleich(Punkt*); bool Gleich(Punkt); void Druck(char *); };
14-30
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
/* Klasse Punkt; Fortsetzung 1*/
Punkt::Punkt() {cout << "Damit ist für den Punkt Speicher
bereitgestellt; die Werte sind undefiniert" << endl;// x = y = 0; ?}
Punkt::Punkt(int x1, int y1) {x = x1; y = y1;}
void Punkt::Verschiebe(int dx, int dy) {x = x + dx;y = y + dy;}
14-31
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
/* Klasse Punkt; Fortsetzung 2*/
void Punkt::Druck(char * s) {cout << "\t" << s << "x-Wert: " << x
<< ", y-Wert: " << y << ";\n";}
bool Punkt::Gleich(Punkt* p) {cout << "(verwendete Version: Zeiger auf Punkte)\n";
if (x == p->x && y == p->y)return true;
else return false;}
bool Punkt::Gleich(Punkt p) {cout << "(verwendete Version: Punkte)\n";return((x == p.x && y == p.y)?true :false);}
14-32
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
/* Klasse Punkt; Fortsetzung 3*/
void Punkt::xSetze(int a) {x = a;}
void Punkt::ySetze(int a) {y = a;}
int Punkt::xWert() {return x;}
int Punkt::yWert() {return y;}
Punkt::~Punkt() {cout << "Destruktor aufgerufen, Wert von
s: "<< s << endl;}
Punkt rt(34, 78);
14-33
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
/* Klasse Punkt; Fortsetzung 4*/
int main() {Punkt p; p.Druck("p:");p.xSetze(4); p.ySetze(7); p.Druck("p: ");Punkt * q = new Punkt(13, 9);q->Druck("q: ");cout << "\tp = q? "; cout << (p.Gleich(*q) ? "true" : "false")
<< endl;p.Verschiebe(9, 2);cout << "\tp = q? "; cout << (p.Gleich(q) ?
"true" : "false") << endl;delete &rt;s = 1;q->~Punkt();s = 2;cout <<"\t Geschafft !"<< endl; return 0;}
Klasse_Punkt
14-34
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Klasse_Punkt: AusgabeDamit ist für den Punkt Speicher bereitgestellt; die Werte sind undefiniert.
p: x-Wert: 234785821, y-Wert: 558996;
p: x-Wert: 4, y-Wert: 7;
q: x-Wert: 13, y-Wert: 9;
p = q? (verwendete Version: Punkte) false
Destruktor aufgerufen, Wert von s: 0
p = q? (verwendete Version: Zeiger auf Punkte)
true
Destruktor aufgerufen, Wert von s: 0
Destruktor aufgerufen, Wert von s: 1
Geschafft !
Destruktor aufgerufen, Wert von s: 2
Destruktor aufgerufen, Wert von s: 2
14-35
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
/* Variation Klasse Punkt; Fortsetzung 5*///Alt:
Punkt::Punkt() {cout << "Damit ist für den Punkt Speicher
bereitgestellt; die Werte sind undefiniert" << endl;}
Punkt::Punkt(int x1, int y1) {x = x1; y = y1;}
Punkt::~Punkt() {cout << "Destruktor aufgerufen, Wert von
s: "<< s << endl;}
14-36
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
/* Variation Klasse Punkt; Fortsetzung 6*///Neu:
Punkt::Punkt() {cout <<"Konstruktor ohne Parameter, x = " << x << "\t y = " << y<< endl;}
Punkt::Punkt(int x1, int y1) {x = x1; y = y1;cout << "Konstruktor mit Parametern,
x = " << x << "\ty = " << y<< endl;
}Punkt::~Punkt() {
cout << "Destruktor mit x = " << x << "\ty = " << y << endl; }
14-37
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
/* Variation Klasse Punkt; Fortsetzung 7*///Neues main + ...:Punkt rt(34, 78);int main() {
Punkt p;p.xSetze(4); p.ySetze(7); Punkt * q = new Punkt(13, 9);cout << "\tp = q? ";cout << (p.Gleich(*q) ? "true" : "false") << endl;p.Verschiebe(9, 2);cout << "\tp = q? ";cout << (p.Gleich(q) ? "true" : "false")
<< endl;delete &rt;p.Verschiebe(9, 2);q->~Punkt();cout << "\t Geschafft !" << endl;return 0;}
Klasse_Punkt
14-38
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Klasse_Punkt_2: AusgabeKonstruktor mit Parametern, x = 34 y = 78
Konstruktor ohne Parameter, x = 135447017 y = 804856
Konstruktor mit Parametern, x = 13 y = 9
p = q? (verwendete Version: Punkte)
false
Destruktor mit x = 13 y = 9
p = q? (verwendete Version: Zeiger auf Punkte)
true
Destruktor mit x = 34 y = 78
Destruktor mit x = 13 y = 9
Geschafft !
Destruktor mit x = 22 y = 11
Destruktor mit x = 34 y = 78
14-39
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Regeln für die Anwendung von Konstruktoren und Destruktoren
1. AllgemeinWerden mehrere globale Objekte oder innerhalb eines Blocks mehrere lokale Objekte definiert, so werden
• die Konstruktoren in der Reihenfolge der Auf-schreibung,• die Destruktoren in der umgekehrten Reihenfolge aufgerufen.
14-40
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Regeln für die Anwendung von Konstruktoren und Destruktoren
2.2. Für ein globales Objekt wird• der Konstruktor zu Beginn der Lebensdauer des Objekts, also vor main,• der Destruktor hinter der schließenden Klammer von main aufgerufen.
3. Für ein lokales Objekt wird• der Konstruktor an der Definitionsstelle des Objekts,• der Destruktor beim Verlassen des definierenden Blocks aufgerufen.
14-41
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Regeln für die Anwendung von Konstruktoren und Destruktoren
4. 4. Für ein dynamisches Objekt wird• der Konstruktor beim Aufruf von new,,
• der Destruktor beim Aufruf von delete für den
zugehörigen Zeiger aufgerufen.
5. 5. Für ein Objekt mit Klassenkomponenten • wird der Konstruktor der Komponenten vor dem Konstruktor der umfassenden Klasse aufgerufen,• am Ende der Lebensdauer werden die Destrukto-
ren in der umgekehrten Reihenfolge aufgerufen.
14-42
Prof. Dr. G. Dittrich10.4.2000
EINI II Kap. 14: Einführung in Klassen
Regeln für die Anwendung von Konstruktoren und Destruktoren
6. Für ein Feld von Objekten wird• bei der Definition für jedes Element beginnend beim Index 0 0 der Konstruktor aufgerufen,• am Ende der Lebensdauer der Destruktor in umgekehrter Reihenfolge für jedes Element aufgerufen.