Das Klassenkonzept von C++ - MISTRAL, TU-Muenchen
Das Klassenkonzept von C++ - MISTRAL, TU-Muenchen
Das Klassenkonzept von C++ - MISTRAL, TU-Muenchen
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
<strong>Das</strong> <strong>Klassenkonzept</strong> <strong>von</strong> <strong>C++</strong><br />
● Eine Klasse definiert einen abstrakten Datentypen, d.h.<br />
– die Schnittstelle und<br />
– die Implementierung <strong>von</strong> Objekten<br />
● Objekte sind die konkreten Instanzen/Ausprägungen<br />
der Klasse<br />
● <strong>Klassenkonzept</strong> <strong>von</strong> <strong>C++</strong> stammt <strong>von</strong> Simula67<br />
– Erweiterung <strong>von</strong> Strukturen durch die Einführung <strong>von</strong> verschatteten<br />
Zustandsvariablen und Methoden<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 35
<strong>Das</strong> <strong>Klassenkonzept</strong> <strong>von</strong> <strong>C++</strong> (2)<br />
● Class klingt objektorientierter als struct<br />
– class{...} = struct { private: ...}<br />
– struct{...}= class{ public: ...}<br />
● Bestandteile einer Klasse - Members:<br />
– Daten: Zustandsvariablen<br />
– Operationen: Methoden<br />
class Name {<br />
public:<br />
...<br />
private:<br />
...};<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 36
Beispiel: Depotverwaltung<br />
● In <strong>C++</strong>:<br />
class Depot {<br />
public: // public members immer zuerst wg. Lesbarkeit<br />
Depot();<br />
// Standardkonstruktor<br />
int Kontostand() {return Barvermögen}; // automatisch inline<br />
void Einzahlung(int betrag) {Barvermögen+=betrag};<br />
private:<br />
int DepotNr;<br />
string Name;<br />
int Barvermögen;<br />
vector Bestand;<br />
};<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 37
Zugriffsregelung<br />
● Der Zugriff auf Members kann folgendermaßen<br />
eingeschränkt werden:<br />
– public: keine Zugriffsbeschränkung<br />
– private: ausschließlich innerhalb der Klasse zugreifbar<br />
Ausnahme: friend Funktionen und Klassen<br />
● Friend-Funktionen und Klassen: erlaubt<br />
klassenexternen Funktionen und anderen Klassen auf<br />
die private Members zuzugreifen<br />
– Friend-Klassen und Friend-Funktionen müssen in der Klassendefinition<br />
deklariert werden<br />
– Achtung: Friends sparsam verwenden, da das Kapselungskonzept<br />
verletzt wird!<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 38
Konstruktoren<br />
● Konstruktoren sind spezielle Methoden der Klassen, die<br />
die Objekte erzeugen und initialisieren<br />
– der Name der Konstruktoren entspricht dem Klassennamen<br />
– vor der Ausführung des Konstruktorrumpfes wird Speicherplatz für die<br />
Zustandsvariablen des Objektes angelegt<br />
– jede Klasse hat einen Standardkonstruktor (default constructor) der bei<br />
der Erzeugung aufgerufen wird<br />
» enthält keine Argumente<br />
» kann selbst definiert werden<br />
» muß immer ohne Klammern aufgerufen werden<br />
– allgemeine Konstruktoren können definiert werden um die Objekte<br />
unterschiedlich zu initialisieren ÅÜberladung<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 39
Konstruktoren (2)<br />
● Copy-Konstruktor C::C(const C& c);<br />
– Erzeugung eines neuen Objektes als eine Kopie eines Objektes<br />
derselben Klasse<br />
– konstante Referenz um eine Änderung der Quelle zu verhindern +<br />
Effizienz<br />
– wird nicht bei Zuweisung ausgeführt!<br />
● Initialisierung der Zustandsvariablen<br />
– im Rumpf des Konstruktors<br />
– als Initialisierungsliste: bevor Rumpf des Konstruktors ausgeführt wird<br />
● Typumwandlungskonstruktoren<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 40
in Header File<br />
Beispiel:<br />
class Depot {<br />
public: // public members immer zuerst wg. Lesbarkeit<br />
Depot();<br />
// Standardkonstruktor<br />
Depot(int Nr, string Name): DepotNr(Nr), Name(Name),<br />
Barvermögen(0) {};<br />
int Kontostand() {return Barvermögen}; // automatisch<br />
inline<br />
...<br />
};<br />
// in .cc file<br />
inline void Depot::Einzahlung(int betrag)<br />
{Barvermögen+=betrag}<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 41
Destruktoren<br />
● Destruktoren verrichten die Aufräumarbeiten, d.h.<br />
Resourcenfreigabe für nicht mehr benötigte Objekte<br />
– Speicherfreigabe, Dateien schließen, etc.<br />
– Destruktoren haben keine Argumente (Å es gibt nur einen pro Klasse)<br />
und keinen Rückgabetyp: ~C()<br />
– Destruktoren werden vom System automatisch erzeugt, wenn nicht<br />
vorgegeben<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 42
weitere <strong>Klassenkonzept</strong>e<br />
● This-Zeiger: this verweist innerhalb einer Methode auf<br />
das aktuelle Objekt<br />
Å *this ist ein Alias für das Objekt selbst<br />
● Konstante Objekte:<br />
– Methoden <strong>von</strong> konstanten Objekten dürfen nicht aufgerufen werden<br />
» Ausnahme: Methode ist als const deklariert und definiert<br />
– const Objekte können nicht durch Methoden geändert werden (auch<br />
nicht durch const Methoden)<br />
» Ausnahmen:<br />
●<br />
●<br />
explizite Typumwandlung: „casting the const away“<br />
mutable Variablen<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 43
Klassenspezifische Members<br />
● static Zustandsvariablen und static Methoden<br />
● existieren nur einmal für die gesamte Klasse: z.B.<br />
Objektzähler, Konstruktoren<br />
● Definition und Initialisierung statischer<br />
Zustandsvariablen nur einmal; außerhalb der<br />
Klassendefinition<br />
● auf static Methoden kann direkt (d.h. ohne Objekt<br />
zugegriffen werden)<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 44
in .h<br />
Beispiel<br />
class numeriertesObjekt // noch nicht vollständig! {<br />
};<br />
public:<br />
numeriertesObjekt();<br />
static int Anzahl() { return anzahl;}<br />
private:<br />
static int anzahl;<br />
// in .cc: Initialisierung und Definition der<br />
//klassenspezifischen Variablen<br />
int numeriertesObjekt::anzahl = 0;<br />
//Aufruf<br />
cout
Konstanten & Templates<br />
● Klassenspezifische Konstanten<br />
– werden innerhalb der Klassendefinition definiert und initialisiert<br />
– sind klassenspezifisch, auch ohne static-Deklaration<br />
class A {<br />
enum Kaptialanlage {Aktie, Fonds, Festgeld};<br />
static const unsigned int maxZahl=1000;<br />
};<br />
● Klassentemplates Å parametrisierte Datentypen<br />
Bsp.: Stack; i.A. Container<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 46
Operatoren auf Klassen<br />
● Überladen <strong>von</strong> Operatoren<br />
– entspricht dem Überladen <strong>von</strong> Funktionen setzt aber Klassen voraus<br />
– Beispiel: += Operator für Strings bedeutet Anfügen<br />
String s1, s2; s1 +=s2; // fügt s2 an s1<br />
– Operatoren können entweder als<br />
» Methoden<br />
ReturnDatentyp operator⊗(Argumentliste) { Code}<br />
» oder als globale Funktionen definiert werden<br />
ReturnDatentyp Klassenname::operator⊗(Argumentliste) { Code}<br />
– alle üblichen Operatoren können überladen werden<br />
» Ausnahme: . .* :: ?:<br />
» es können keine neuen Operatorsymbole definiert werden<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 47
Vererbung: IS-A Hierarchien<br />
● Vererbung ist ein wichtiges Konzept der Abstraktion<br />
– Zusammenfassung <strong>von</strong> Objekten mit gemeinsamen Eigenschaften Å<br />
Klassifikation <strong>von</strong> Objekten (sog. is-a Hierarchie)<br />
– Oberklasse: Generalisierung/Abstraktion der Unterklassen<br />
– Unterklasse: Spezialisierung der Oberklasse<br />
– Beispiel: Fahrzeug<br />
Landfahrzeug<br />
Wasserfahrzeug<br />
Luftfahrzeug<br />
PKW LKW Motorboot Segelboot<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 48
Vererbung in <strong>C++</strong><br />
● Syntax: class Klassename : public Oberklassenname<br />
● Die Unterklasse (Subclass) erbt <strong>von</strong> der Oberklasse<br />
(Superclass):<br />
– alle Eigenschaften: die Zustandsvariablen<br />
– das Verhalten: die Methoden<br />
ÅWiederverwendung: nur Abweichungen, Spezialisierungen müssen<br />
berücksichtigt werden<br />
– Beispiele:<br />
» alle Fahrzeuge haben Abmaße: Höhe, Länge, Breite<br />
» Methoden ablegen, ankern, etc. aber nur für Wasserfahrzeuge<br />
sinnvoll<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 49
class Fahrzeug {<br />
Beispiel<br />
public:<br />
Fahrzeug();<br />
Fahrzeug(double, double, double);<br />
void bewegen();<br />
private:<br />
double hoehe, laenge, breite;<br />
};<br />
class Wasserfahrzeug : public Fahrzeug {<br />
public:<br />
void anlegen();<br />
void ankern();<br />
};<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 50
Vererbung in <strong>C++</strong> (2)<br />
● Realisierung der Vererbung: Objekt der Subklasse<br />
enthält anonymes Subobjekt der Superklasse<br />
● Klassen in <strong>C++</strong> sind Typen Å abgeleitete Klasse<br />
definiert Subtyp<br />
– Objekt der Subklasse ist zuweisungskompatibel zu einem Objekt der<br />
Superklasse:<br />
Fahrzeug A;<br />
Landfahrzeug B;<br />
A = B; // Inhalt des Subobjekts <strong>von</strong> B wird nach A<br />
kopiert<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 51
Vererbung in <strong>C++</strong> (3)<br />
● Initialisierung:<br />
– impliziter Aufruf der Konstruktoren der Superklassen bei Initialisierung<br />
im Rumpf<br />
Landfahrzeug(double h, double l, double b)<br />
{ hoehe=h; laenge=l, breite=b;}<br />
– expliziter Aufruf der Konstruktoren der Superklassen in der<br />
Initialisierungsliste<br />
Landfahrzeug(double h, double l, double b)<br />
: Fahrzeug(h, l, b) { }<br />
– Initialisierung mit einer Initialisierungsliste ist generell vorzuziehen, weil<br />
das Objekt in einem Schritt mit den richtigen Werten initialisiert wird.<br />
Die Initialisierungsliste darf enthalten:<br />
» Elemente der Klasse (außer vererbte)<br />
» Konstruktoraufrufe der Superklassen<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 52
Vererbung: Implementierungshierarchie<br />
● <strong>C++</strong> unterstützt nicht nur IS-A Hierarchien sondern auch<br />
beliebige Implementierungshierarchien<br />
Å man spricht allgemeiner <strong>von</strong>: Ableitung<br />
● Beispiel: Kreis erbt <strong>von</strong> Punkt, aber Kreis ist kein Punkt!<br />
Punkt<br />
int x<br />
int y<br />
Kreis<br />
int x<br />
int y<br />
int radius<br />
double fläche()<br />
double umfang()<br />
Ellipse<br />
int x<br />
int y<br />
int radius<br />
int radius_y<br />
double fläche()<br />
double umfang()<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 53
Überladen <strong>von</strong> Methoden -<br />
Polymorphismus<br />
● Generell: Methoden der Superklasse können in der<br />
Subklasse überschrieben werden Å Spezialisierung<br />
Beispiel: für Kreise und Ellipsen wird fläche()<br />
unterschiedlich berechnet<br />
● Achtung: nur virtuelle Methoden der Superklasse in<br />
den Subklassen überschreiben!!<br />
– virtuelle Funktionen garantieren richtige Methodenauflösung zur<br />
Laufzeit, da Typinformation über das Objekt mitgegeben wird<br />
● Achtung: bei unstimmiger Signatur wird auf Methoden<br />
der Superklasse durchgegriffen (wenn dort vorhanden)!<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 54
class A {<br />
public: double foo() {return<br />
0;};<br />
};<br />
class B : public A {<br />
public: double foo() {return<br />
1;};<br />
};<br />
A a;<br />
B b;<br />
A *ptr;<br />
ptr = &a;<br />
cout foo(); // Ausgabe: 0<br />
ptr = &b;<br />
cout foo(); // Ausgabe: 0<br />
Beispiel<br />
class A {<br />
public: virtual double foo()<br />
{return 0;};<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 55<br />
};<br />
class B : public A {<br />
public: double foo() {return<br />
1;};<br />
};<br />
A a;<br />
B b;<br />
A *ptr;<br />
ptr = &a;<br />
cout foo();<br />
ptr = &b;<br />
cout foo();<br />
// Ausgabe: 0<br />
// Ausgabe: 1
Zugriffsschutz<br />
● public und private Deklaration der Superklasse gilt<br />
auch für Objekte der Subklasse<br />
– Zugriffsdeklaration wird mit vererbt<br />
– Schutz der Kapselung: private Members sind in einer abgeleiteten<br />
Klasse nicht zugreifbar<br />
● Neue Zugriffspolitik: protected Members<br />
– protected Members sind in der eigenen und in (public) abgeleiteten<br />
Klassen zugreifbar; sonst wie private<br />
● Spezialfälle: protected und public Vererbung<br />
– Vererbung der Implementierung, aber nicht der Schnittstelle<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 56
Zugriffsschutz (2)<br />
● Spezialfälle: protected und private Vererbung<br />
– Wie werden die public und protected Members vererbt?<br />
– als protected: class A : protected B {};<br />
– als private: class A: private B {};<br />
ÅVererbung der Implementierung, aber nicht der Schnittstelle<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 57
Mehrfachvererbung<br />
● Mehrfachvererbung bietet mehr Flexibilität bei der<br />
Modellierung<br />
Fahrzeug<br />
● Beispiel:<br />
Landfahrzeug<br />
Wasserfahrzeug<br />
Amphibienfahrzeug<br />
● In <strong>C++</strong>: Angabe mehrerer Superklassen<br />
– Subklasse erbt alle Members (Zustandsvariablen & Methoden) aller<br />
Superklasse<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 58
Mehrfachvererbung (2)<br />
● Probleme: Namenskonflikte und Mehrdeutigkeiten<br />
– Namenskonflikte: explizite Angabe der Basisklasse erforderlich<br />
– Mehrfache Erzeugung <strong>von</strong> Subobjekten der gleichen Basisklasse (z.B.<br />
Fahrzeug)<br />
Lösung: virtuelle Basisklassen<br />
class Landfahrzeug : virtual public Fahrzeug {...};<br />
class Wasserfahrzeug : virtual public Fahrzeug {...};<br />
class Amphibienfahrzeug : public Landfahrzeug, public<br />
Wasserfahrzeug {...};<br />
● Vergleich zu Java:<br />
– keine Mehrfachvererbung aber Interfaces Å Vorteile der<br />
Mehrfachvererbung ohne deren Probleme<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 59
● Abstrakte Klassen<br />
Abstrakte Klassen<br />
– enthalten sehr allgemeinen (oft nicht veränderbaren) Code<br />
– dienen nur als Superklassen der Vererbungshierarchie<br />
Å es werden keine Objekte der Klasse erzeugt<br />
● Abstrakte Klassen über rein virtuelle Methoden<br />
– rein virtuelle Methode:<br />
» i.A. keinen Definitionsteil und Zusatz: „=0“<br />
Beispiel:<br />
virtual int rein_virtuell(int, int) =0;<br />
– konkrete Klassen (d.h. Klassen für die Objekte angelegt werden)<br />
müssen Implementierung für die virtuellen Methoden bereitstellen<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 60
Exkurs: IS-A vs. PART-OF<br />
● IS-A: A ist eine Spezialisierung <strong>von</strong> B Å Vererbung<br />
class A : public B { };<br />
– Members <strong>von</strong> B sind Members <strong>von</strong> A!<br />
● PART-OF: A enthält B Å A enthält B als Komponente<br />
class A {<br />
B b;<br />
};<br />
– A kann Schnittstelle <strong>von</strong> B benutzen<br />
© 2000 Dr. Volker Markl Vorlesung Praxis der Softwareentwicklung - Teil 2: <strong>C++</strong> 61