19.11.2013 Aufrufe

Das Klassenkonzept von C++ - MISTRAL, TU-Muenchen

Das Klassenkonzept von C++ - MISTRAL, TU-Muenchen

Das Klassenkonzept von C++ - MISTRAL, TU-Muenchen

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!