Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.

Ähnliche Präsentationen


Präsentation zum Thema: "Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund."—  Präsentation transkript:

1 Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund

2 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 2 Kapitel 10: Klassen Inhalt Einführung Konstruktoren / Destruktoren Kopierkonstruktor Selbstreferenz Überladen von Operatoren …

3 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 3 Ziele von Klassen Kapselung von Attributen (wie struct in Programmiersprache C) Kapselung von klassenspezifischen Funktionen / Methoden Effiziente Wiederverwendbarkeit - Vererbung - Virtuelle Methoden Grundlage für Designkonzept für Software Kapitel 10: Klassen

4 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 4 Schlüsselwort: class Datentypdefinition / Klassendefinition analog zu struct struct Punkt { double x, y; }; class Punkt { double x, y; }; Unterschied: Punkt p; p.x = 1.1; p.y = 2.0; Punkt p; p.x = 1.1; p.y = 2.0; ? Zugriff gesperrt! Kapitel 10: Klassen

5 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 5 Schlüsselwort: class Datentypdefinition / Klassendefinition analog zu struct struct Punkt { double x, y; }; class Punkt { double x, y; }; Komponenten sind öffentlich! ( public ) Komponenten sind privat! ( private ) Kontrolle über Zugriffsmöglichkeit sollte steuerbar sein! Man benötigt Mechanismus, um auf Komponenten zugreifen zu können! Kapitel 10: Klassen

6 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 6 struct Punkt { double x, y; }; void SetzeX(Punkt &p, double w); void SetzeY(Punkt &p, double w); double LeseX(Punkt &p); double LeseY(Punkt &p); prozedural class Punkt { double x, y; public: void SetzeX(double w); void SetzeY(double w); double LeseX(); double LeseY(); }; objekt-orientiert Schlüsselwort public : alles Nachfolgende ist öffentlich zugänglich! Kapitel 10: Klassen

7 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 7 struct Punkt { double x, y; }; void Verschiebe(Punkt &p, double dx, double dy); bool Gleich(Punkt &a, Punkt& b); double Norm(Punkt &a); class Punkt { private: double x, y; public: void SetzeX(double w); void SetzeY(double w); double LeseX(); double LeseY(); void Verschiebe(double dx, double dy); bool Gleich(Punkt &p); double Norm(); }; Kapitel 10: Klassen

8 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 8 class Punkt { private: double x, y; public: void SetzeX(double w) { x = w; } void SetzeY(double w) { y = w; } double LeseX() { return x; } double LeseY() { return y; } void Verschiebe(double dx, double dy); bool Gleich(Punkt &p); double Norm(); }; void Punkt::Verschiebe(double dx, double dy) { x += dx; y += dy; } Implementierung: direkt in der Klassendefinition Implementierung: außerhalb der Klassendefinition Kapitel 10: Klassen

9 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 9 Prinzip des information hiding Trennung von Klassendefinition und Implementierung am besten in verschiedenen Dateien! Punkt.hPunkt.cpp Klassen- definition Klassen- implementierung *.h header*.cpp cplusplus bei Implementierung außerhalb der Klassendefinition: Angabe des Klassennames nötig! Datentyp Klassenname::Methode(…){ } Kapitel 10: Klassen

10 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 10 class Punkt { private: double x, y; public: void SetzeX(double w); void SetzeY(double w); double LeseX(); double LeseY(); void Verschiebe(double dx, double dy); bool Gleich(Punkt &p); double Norm(); }; Datei: Punkt.h Die Klassendefinition wird nach außen (d.h. öffentlich) bekannt gemacht! Die Implementierung der Methoden wird nach außen hin verborgen! Kapitel 10: Klassen

11 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 11 #include #include "Punkt.h" void Punkt::SetzeX(double w) { x = w; } void Punkt::SetzeY(double w) { y = w; } double Punkt::LeseX() { return x; } double Punkt::LeseY() { return y; } void Punkt::Verschiebe(double dx, double dy) { x += dx; y += dy; } bool Punkt::Gleich(Punkt &p) { return x == p.LeseX() && y == p.LeseY() ? true : false; } double Punkt::Norm() { return sqrt(x * x + y * y); } Datei: Punkt.cpp Kapitel 10: Klassen

12 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 12 Überladen von Methoden class Punkt { private: double x, y; public: bool Gleich(Punkt &p); bool Gleich(double ax, double ay) { return (x == ax && y == ay) ? true : false; }; mehrere Methoden mit gleichem Namen wie unterscheidbar? durch ihre verschiedenen Signaturen / Argumentlisten! Punkt p1, p2; // … if (p1.Gleich(p2) || p1.Gleich(1.0, 2.0)) return; Kapitel 10: Klassen

13 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 13 Initialisierung umständlich: Punkt p; p.SetzeX(1.3); p.SetzeY(2.9); ? wie bei struct Punkt ? Punkt p = { 1.3, 2.9 }; Konstruktoren class Punkt { private: double x, y; public: Punkt() { x = y = 0.0; } Punkt(double ax, double ay) { x = ax; y = ay; } }; Punkt p1; Punkt p2(1.3, 2.9); ! identisch zu: Punkt p1(0,0); Kapitel 10: Klassen

14 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 14 Aufgaben eines Konstruktors: Saubere Initialisierung eines Objekts man kann erzwingen, dass nur initialisierte Instanzen erzeugt werden ggf. Bereitstellung von dynamischen Speicherplatz ggf. Benachrichtigung eines anderen Objekts über Erzeugung (Registrierung) durch Überladen: bequeme Möglichkeiten zur Initialisierung Bsp: Default-Werte Punkt(); z.B. wie Punkt(0.0, 0.0) Punkt(double x); z.B. wie Punkt(x, 0.0); Punkt(double x, double y); was immer gerade nötig ist … Kapitel 10: Klassen

15 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 15 Merke: Konstruktoren heißen exakt wie die Klasse, zu der sie gehören! Wenn eine Instanz einer Klasse angelegt wird automatischer Aufruf des Konstruktors! Da nur Instanz angelegt wird (Speicherallokation und Initialisierung) wird kein Wert zurückgegeben kein Rückgabewert (auch nicht void ) Konstruktoren können überladen werden bei mehreren Konstruktoren wird der ausgewählt, der am besten zur Signatur / Argumentliste passt eindeutig! Kapitel 10: Klassen

16 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 16 Instanzen von Klassen können auch dynamisch erzeugt werden: Punkt *p1 = new Punkt(2.1, 3.3); Punkt *p2 = new Punkt(); Punkt *p3 = new Punkt; gleichwertig! Achtung! Das Löschen nicht vergessen! Speicherplatzfreigabe! delete p1; etc. Kapitel 10: Klassen

17 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 17 Destruktoren dual zu Konstruktoren automatischer Aufruf, wenn Instanz Gültigkeitsbereich verlässt heißen exakt wie die Name der Klasse, zu der sie gehören Unterscheidung von Konstruktoren bzw. Kennzeichnung als Destruktor durch vorangestellte Tilde ~ Bsp: ~Punkt(); Destruktoren haben niemals Parameter Zweck: Aufräumarbeiten - z.B. Schließen von Dateien - z.B. Abmeldung bei anderen Objekten (Deregistrierung) - z.B. Freigabe von dynamischen Speicher, falls vorher angefordert - … und was immer gerade nötig ist Kapitel 10: Klassen

18 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 18 Illustration: Punkt::Punkt(double ax, double ay) { x = ax; y = ay; cout << Konstruktor aufgerufen! << endl; } Punkt::~Punkt() { cout << Destruktor aufgerufen! << endl; } int main() { cout << Start << endl; { Punkt p(1.0, 2.0); } cout << Ende << endl; } Ausgabe: Start Konstruktor aufgerufen! Destruktor aufgerufen! Ende Kapitel 10: Klassen

19 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 19 Punkt::Punkt(double ax, double ay) { x = ax; y = ay; cout << K: << x << << y << endl; } Punkt::~Punkt() { cout << D: << x << << y << endl; } Noch ein Beispiel … int main() { cout << Start << endl; Punkt p1(1.0, 0.0); Punkt p2(2.0, 0.0); cout << Ende << endl; } Ausgabe: Start K: K: Ende D: D: Konstruktoren: Aufruf in Reihenfolge der Datendefinition Destruktoren: Aufruf in umgekehrter Reihenfolge Kapitel 10: Klassen

20 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 20 Großes Beispiel … Punkt g1(-1.0, 0.0); Punkt g2(-2.0, 0.0); int main() { cout << "Main Start" << endl; Punkt q1(0.0, 1.0); { cout << "Block Start" << endl; Punkt p1(1.0, 0.0); Punkt p2(2.0, 0.0); Punkt p3(3.0, 0.0); cout << "Block Ende" << endl; } Punkt q2(0.0, 2.0); cout << "Main Ende" << endl; } Punkt g3(-3.0, 0.0); Kapitel 10: Klassen

21 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 21 class Punkt { private: int id; public: Punkt(); ~Punkt(); }; Punkt.h static int cnt = 1; Punkt::Punkt() : id(cnt++) { cout << "K" << id << endl; } Punkt::~Punkt() { cout << "D" << id << endl; } Punkt.cpp Hack! Nur für Demozwecke! int main() { cout << "Start" << endl; { cout << "Block Start" << endl; Punkt menge[3]; cout << "Block Ende" << endl; } cout << "Ende" << endl; return 0; } Start Block Start K1 K2 K3 Block Ende D3 D2 D1 Ende Ausgabe: Feld / Array Kapitel 10: Klassen

22 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 22 Regeln für die Anwendung für Konstruktoren und Destruktoren 1.Allgemein Bei mehreren globalen Objekten oder mehreren lokalen Objekten innerhalb eines Blockes werden -die Konstruktoren in der Reihenfolge der Datendefinitionen und -die Destruktoren in umgekehrter Reihenfolge aufgerufen. 2.Globale Objekte -Konstruktor wird zu Beginn der Lebensdauer (vor main) aufgerufen; -Destruktor wird hinter der schließenden Klammer von main aufgerufen. 3.Lokale Objekte -Konstruktor wird an der Definitionsstelle des Objekts aufgerufen; -Destruktor wird beim Verlassen des definierenden Blocks aufgerufen. Kapitel 10: Klassen

23 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 23 Regeln für die Anwendung für Konstruktoren und Destruktoren 4.Dynamische Objekte -Konstruktor wird bei new aufgerufen; -Destruktor wird bei delete für zugehörigen Zeiger aufgerufen. 5.Objekt mit Klassenkomponenten -Konstruktor der Komponenten wird vor dem der umfassenden Klasse aufgerufen; -am Ende der Lebensdauer werden Destruktoren in umgekehrter Reihenfolge aufgerufen. 6.Feld von Objekten -Konstruktor wird bei Datendefinition für jedes Element beginnend mit Index 0 aufgerufen; -am Ende der Lebensdauer werden Destruktoren in umgekehrter Reihenfolge aufgerufen. Kapitel 10: Klassen

24 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 24 Kopierkonstruktor (copy constructor) class Punkt { private: double x, y; public: Punkt(double ax, double bx); Punkt(const Punkt& p); ~Punkt(); }; Kopierkonstruktor Punkt::Punkt(const Punkt& p) { x = p.x; y = p.y; } Kann wie eine Zuweisung interpretiert werden! Entstehendes Objekt wird mit einem bestehenden Objekt initialisiert! Punkt::Punkt(const Punkt& p) : x(p.x), y(p.y) { } alternativ: wirkt wie Zuweisung; geht nur bei Klassenelementen Kapitel 10: Klassen

25 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 25 Kopierkonstruktor (copy constructor) Bauplan: ObjektTyp ( const ObjektTyp & bezeichner) ; Kopierkonstruktor liefert / soll liefern byteweises Speicherabbild des Objektes Wird automatisch aufgerufen, wenn: 1.ein neues Objekt erzeugt und mit einem bestehenden initialisiert wird; 2.ein Objekt per Wertübergabe an eine Funktion gereicht wird; 3.ein Objekt mit return als Wert zurückgegeben wird. Was passiert, wenn ich keinen Kopierkonstruktor implementiere? Punkt a(1.2, 3.4); // Neu Punkt b(a); // Kopie Punkt c = b; // Kopie b = a; // Zuweisung! Kapitel 10: Klassen

26 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 26 Kopierkonstruktor (copy constructor) Wird für eine Klasse kein Kopierkonstruktur implementiert, dann erzeugt ihn der Compiler automatisch! Achtung! Es wird dann ein byteweises Speicherabbild des Objektes geliefert! ) flache Kopie (engl. shallow copy) Problem: - Konstruktor fordert dynamischen Speicher an - Konstruktor öffnet exklusive Datei (o.a. Resource) nur Kopie des Zeigers nicht teilbar! Crash! ) dann tiefe Kopie (engl. deep copy) nötig! ) man muss Kopierkonstruktor (und Destruktor) implementieren! Kapitel 10: Klassen

27 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 27 class CZeit { private: int mStd, mMin, mSek; public: CZeit(); // Konstruktor CZeit(int std, int min = 0, int sek = 0); // Konstruktor CZeit(const CZeit& aZeit); // Kopierkonstruktor void Anzeigen(); int Std(); int Min(); int Sek(); static CZeit Jetzt(); // statische Klassenfunktion }; CZeit addiere(CZeit z1, CZeit z2); // globale Funktion Default-Werte Klassendefinition Kapitel 10: Klassen

28 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 28 CZeit::CZeit() : mStd(0), mMin(0), mSek(0) { } CZeit::CZeit(int aStd, int aMin, int aSek) : mStd(aStd), mMin(aMin), mSek(aSek) { assert(mStd >= 0 && mStd = 0 && mMin = 0 && mSek < 60); } CZeit::CZeit(const CZeit& aZeit) : mStd(aZeit.mStd), mMin(aZeit.mMin), mSek(aZeit.mSek) { } Konstruktoren CZeit CZeit::Jetzt() { time_t jetzt = time(0); struct tm *hms = localtime(&jetzt); CZeit z(hms->tm_hour, hms->tm_min, hms->tm_sec); return z; } statische Elementfunktion Kapitel 10: Klassen

29 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 29 CZeit addiere(CZeit z1, CZeit z2) { int std = z1.Std() + z2.Std(); int min = z1.Min() + z2.Min(); int sek = z1.Sek() + z2.Sek(); CZeit zeit(std, min, sek); return zeit; } int CZeit::Std() { return mStd; } int CZeit::Min() { return mMin; } int CZeit::Sek() { return mSek; } void CZeit::Anzeigen() { cout << mStd << ':' << mMin << ':' << mSek << endl; } CZeit addiere(CZeit z1, CZeit z2) { CZeit zeit; zeit.mStd = z1.mStd + z2.mStd; // usw } ACHTUNG ! Externer Zugriff auf private Daten! Zugriff gesperrt! Funktioniert so nicht! Hier muss noch dafür gesorgt werden, dass der Konstruktor keine Assertion wirft! Kapitel 10: Klassen

30 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 30 Verschönerung der Zeitanzeige void CZeit::Anzeigen() { cout << mStd << ':' << mMin << ':' << mSek << endl; } bisher: CZeit z(12,5,34); z.Anzeigen(); liefert Ausgabe: 12:5:34 wir wollen haben: 12:05:34 void CZeit::Anzeigen() { if (mStd < 10) cout << "0"; cout << mStd << ":"; if (mMin < 10) cout << "0"; cout << mMin << ":"; if (mSek < 10) cout << "0"; cout << mSek << endl; } … liefert 12:05:34 Kapitel 10: Klassen

31 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 31 #include #include "CZeit.h" using namespace std; int main(){ CZeit z(CZeit::Jetzt()); z.Anzeigen(); CZeit a(1,0,0); CZeit sum; sum = addiere(z, a); sum.Anzeigen(); return 0; } Testprogramm Ausgabe (z.B.): 14:45:21 15:45:21 schöner wäre ja: sum = z + a; Überladen von Operatoren! (später …) Kapitel 10: Klassen

32 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 32 void CZeit::normalize() { mMin += mSek / 60; mSek %= 60; mStd += mMin / 60; mMin %= 60; mStd %= 24; } Normalisierung class CZeit { private: int mStd, mMin, mSek; void normalize(); public: … }; Private Hilfsfunktion: kann nur innerhalb der Klassenimplementierung aufgerufen werden! setzt beliebige nichtnegative Werte auf normale Werte: 0 mStd < 24 0 mMin < 60 0 mSek < 60 Kapitel 10: Klassen

33 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 33 Konstruktor: 2. Version CZeit::CZeit(int aStd, int aMin, int aSek) : mStd(aStd), mMin(aMin), mSek(aSek) { normalize(); } Problem: negative Eingaben werden via normalize() nicht repariert Konstruktor: 3. Version CZeit::CZeit( unsigned int aStd, unsigned int aMin, unsigned int aSek ) : mStd(aStd), mMin(aMin), mSek(aSek) { normalize(); } Lösung: nichtnegative Eingaben erzwingen via unsigned int in Argumentliste des Konstruktors Kapitel 10: Klassen

34 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 34 Selbstreferenz class CZeit { … CZeit& addStd(int n); CZeit& addMin(int n); CZeit& addSek(int n); } CZeit& addMin(int n) { mMin += n; normalize(); return *this; } CZeit x = CZeit::Jetzt(); CZeit z = x.addStd(1).addMin(21); Bsp: Schlüsselwort: this this ist Zeiger auf das Objekt, für das die Elementfunktion aufgerufen wurde. *this bezieht sich auf das Objekt selbst. für 3. Version: unsigned int Kapitel 10: Klassen

35 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 35 Operator ist eine Verknüpfungsvorschrift! Kann man auffassen als Name einer Funktion: Bsp: Addition a + b interpretieren als + (a, b) in C++ als: c = operator+ (a, b) Überladen von Operatoren FunktionsnameArgumente Zweck: eine Klasse mit Funktionalität ausstatten, die vergleichbar mit elementarem Datentyp ist! Vorteil: Quellcode wird übersichtlicher Kapitel 10: Klassen

36 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 36 Überladen von Operatoren Welche? +^==+=^=!=<<() -&>-=&=&&<<=new *|>=*=|=||>>delete /~>>== %!<=%=--->*[] Wie? Objekttyp& operator (const ObjektTyp& bezeichner) Objekttyp operator (const ObjektTyp& bezeichner) Kapitel 10: Klassen

37 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 37 Überladen von Operatoren CZeit& operator= (const CZeit& aZeit) { mStd = aZeit.mStd; mMin = aZeit.mMin; mSek = aZeit.mSek; return *this; } bool operator== (const CZeit& aZeit) { if (aZeit.mStd != Std()) return false; if (aZeit.mMin != Min()) return false; if (aZeit.mSek != Sek()) return false; return true; } Test auf Gleichheit Zuweisung Kapitel 10: Klassen

38 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 38 Wenn für eine Klasse der Zuweisungsoperator nicht überschrieben wird, dann macht das der Compiler automatisch! Vorsicht! Speicher des Objektes wird byteweise überschrieben! Problem: z.B. wenn Objekt dynamischen Speicher verwendet ) gleiche Problematik wie beim Kopierkonstruktor Merke: Wenn die Implementierung eines Kopierkonstruktors nötig ist, dann höchstwahrscheinlich auch Destruktor und überschriebene Zuweisung! Kapitel 10: Klassen

39 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 39 Unterschied zwischen Kopierkonstruktor und Zuweisung Kopierkonstruktor: Initialisierung einer neu deklarierten Variable von existierender Variable Zuweisung: wirkt zwar wie Kopierkonstruktor (flache Kopie bzw. tiefe Kopie), überschreibt jedoch Speicher der existierenden Variable mit dem Speicher der zuweisenden, existierenden Variable zusätzlich ggf. Aufräumen: Freigabe dynamischer Speicher! außerdem: Rückgabe einer Referenz auf sich selbst Kapitel 10: Klassen

40 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 40 Überladen von Operatoren CZeit CZeit::operator+ (const CZeit& aZeit) { CZeit z(*this); z += aZeit; // Normalisierung via += return z; } CZeit& CZeit::operator+= (const CZeit& aZeit) { mStd += aZeit.mStd; mMin += aZeit.mMin; mSek += aZeit.mSek; normalize(); return *this; } Addition mit Zuweisung Addition Kapitel 10: Klassen

41 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 41 Test int main() { CZeit x(0,0,86399);// 23:59:59 x.Anzeigen(); x.addSek(1);// 00:00:00 x.Anzeigen(); x.addStd(12).addMin(13).addSek(14).Anzeigen(); // 12:13:14 CZeit z1 = CZeit::Jetzt();// statische Elementfunktion CZeit z2 = z1; // Zuweisung, nutzt aber Kopierkonstruktor! z1.Anzeigen(); if (z1 == z2) // Operator == überladen cout << "Gleich!" << endl; CZeit a(1), b(0,1), c(0,0,1);// Nutzung der Defaults z1 += a; // Operator += überladen z1.Anzeigen(); Fortsetzung auf nächster Folie … Kapitel 10: Klassen

42 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 42 Fortsetzung … CZeit s; // Konstruktor für 00:00:00 s.Anzeigen(); s += a + b + c;// Operatoren += und + überladen s.Anzeigen(); CZeit t; t = a + b + c; // Operatoren = und + überladen; // Zuweisung nutzt überladenes = t.Anzeigen(); } Kapitel 10: Klassen

43 Kapitel 10 G. Rudolph: Einführung in die Programmierung WS 2008/09 43 Kapitel 10: Klassen


Herunterladen ppt "Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund."

Ähnliche Präsentationen


Google-Anzeigen