Praxis der Programmierung

Ähnliche Dokumente
Praxis der Programmierung

Thema heute: Vererbung und Klassenhierarchien. Abgeleitete Klassen. Vererbung von Daten und Funktionen. Virtuelle Funktionen

C++ Notnagel. Ziel, Inhalt. Programmieren in C++

Mapra: C++ Teil 6. Felix Gruber, Sven Groß. IGPM, RWTH Aachen. 13. Juni 2017

Einstieg in die Informatik mit Java

7. Übung Informatik II - Objektorientierte Programmierung

Angewandte Mathematik in OOP WS 2011/12. Abschluss-Test

Einstieg in die Informatik mit Java

Einstieg in die Informatik mit Java

Objektorientierte Programmierung und Klassen

Vererbung I. Kfz Eigenschaften und Methoden der Klasse Kfz Lkw. Pkw. Eigenschaften und Methoden der Klasse Kfz

HSR Rapperswil 2001 Markus Rigling. Programmieren: Vererbung. 1 Variante 2

C++ - Objektorientierte Programmierung Vererbung

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 23

Programmieren II Abstrakte Klassen / Virtuelle Methoden. Programmieren II Abstrakte Klassen / Virtuelle Methoden

Vererbung. Gerd Bohlender. Institut für Angewandte und Numerische Mathematik. Vorlesung: Einstieg in die Informatik mit Java 23.5.

Vererbung, Polymorphie

C++ - Einführung in die Programmiersprache Header-Dateien und Funktionen. Leibniz Universität IT Services Anja Aue

OOP und Angewandte Mathematik. Eine Einführung in die Anwendung objektorientierter Konzepte in der angewandten Mathematik

Grundkurs C++ IDE Klassenhierarchien

Grundelemente objektorientierter Sprachen (1)

Grundelemente objektorientierter Sprachen (1)

Polymorphismus 179. Function.h. #include <string>

Polymorphismus 44. Function.hpp. #include <string>

Einstieg in die Informatik mit Java

Objektorientierte Programmierung mit C++ SS 2007

Überblick. R.Grossmann / P. Sobe 1

Vererbung und Polymorphie

Grundkurs C++ IDE Klassenhierarchien

Grundkurs C++ IDE Klassenhierarchien

Grundelemente objektorientierter Sprachen (1)

C++ Teil 12. Sven Groß. 18. Jan Sven Groß (IGPM, RWTH Aachen) C++ Teil Jan / 11

Programmierung und Angewandte Mathematik

OOP und Angewandte Mathematik (Praktikum 1) Eine Einführung in die Anwendung objektorientierter Konzepte in der angewandten Mathematik

6. Globalübung (zu Übungsblatt 8)

Programmieren in Java

Thema heute: Vererbung und Klassenhierarchien. Abgeleitete Klassen. Vererbung von Daten und Funktionen. Virtuelle Funktionen

2.13 Vererbung. Rainer Feldmann Universität Paderborn Technische Informatik für Ingenieure (TIFI) WS 09/ Article

Überblick. 5. Objekt und Klasse, Elementfunktionen

Vorlesung Datenstrukturen

Crashkurs C++ Wiederholung

Objektorientiertes Programmieren mit C++ für Fortgeschrittene

Einstieg in die Informatik mit Java

Institut für Programmierung und Reaktive Systeme. Java 7. Markus Reschke

C++ Klassen, Vererbung. Philipp Lucas. Sebastian Hack. Wintersemester 2008/09. saarland.

Einführung in die Programmierung mit C++

Prof. Dr. Markus Gross Informatik I für D-ITET (WS 03/04)

Repetitorium Informatik (Java)

Programmierung Nachklausurtutorium

Programmieren in Java

Implementieren von Klassen

Objektorientierte Anwendungsentwicklung

Prüfung aus PROGRAMMIEREN (2) (C++) (WS 2002/03)

Einführung in C# Teil 3. Matthias Nübling

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 29

Centrum für Informations- und Sprachverarbeitung SoSe 2018: Höhere Programmierung mit C++ Andreas Krieger. Musterlösung 9

Grundlagen der Informatik

Praxisorientierte Einführung in C++ Lektion: "Vererbung"

Vorlesungsprüfung Programmiersprache 1

Kapitel 13. Abstrakte Methoden und Interfaces. Fachgebiet Knowledge Engineering Prof. Dr. Johannes Fürnkranz

Kapitel 13. Definition von Klassen. OOP Thomas Klinker 1

Javakurs FSS Lehrstuhl Stuckenschmidt. Tag 3 - Objektorientierung

C++ - Objektorientierte Programmierung Polymorphie

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 29

7.2 Dynamischer Speicher in Objekten/Kopierkonstruktor

C++ Klassen weitere Funktionen

Methoden. von Objekten definiert werden, Methoden,, Zugriffsmethoden und Read-Only

Einstieg in die Informatik mit Java

Abend 4 Übung : Erweitern von Klassen durch Vererbung

Informationsverarbeitung im Bauwesen

Objektorientierung (OO)

11.3 Virtuelle Methoden

C++ Teil 5. Sven Groß. 13. Mai Sven Groß (IGPM, RWTH Aachen) C++ Teil Mai / 18

DAP2-Programmierpraktikum Einführung in C++ (Teil 2)

Vorausgesetzte Grundkenntnisse. Inhalt. Klassenhierarchie und Vererbung. Vererbung. Klassenhierarchie und Vererbung. Einführung in C# Teil 3

Vorkurs Informatik WiSe 15/16

Vorkurs Informatik: Erste Schritte der Programmierung mit C++

C++ - Objektorientierte Programmierung Konstante und statische Elemente

Praxis der Programmierung

Humboldt-Universität zu Berlin Wintersemester 2010/11 Institut für Informatik Grundlagen der Programmierung. 6. Übungsblatt

Programmierung III. Pointer für Fortgeschrittene Marc Ruberg. Arrays von Pointern ( Zeigervektoren ): Pointer auf Pointer:

Übung zur Vorlesung Wissenschaftliches Rechnen Sommersemester 2012 Auffrischung zur Programmierung in C++, 2. Teil

Praxis der Programmierung

Kapitel 9. Programmierkurs. Attribute von Klassen, Methoden und Variablen. 9.1 Attribute von Klassen, Methoden und Variablen

Tag 7 Repetitorium Informatik (Java)

C++ - Variablen: Gültigkeit - Sichtbarkeit

Objektorientierte Programmierung

Objektorientiert in C++

Innere Klassen. Gerd Bohlender. Institut für Angewandte und Numerische Mathematik. Vorlesung: Einstieg in die Informatik mit Java

Übersicht. Bisherige Verwendung von Klassen Vererbung. Zeiger auf Objekte (abgeleiteter) Klassen Virtuelle Funktionen Konstruktoren/Destruktoren

Einführung in die Programmiersprache Java II

Die abgeleiteten Klassen Kreis und Viereck erben die Elemente des Basisklasse und verfügen über zusätzliche Eigenschaften (Seitenlänge,

Objektorientierung Grundlagen

4. Vererbung Die Klasse Object. Die Klasse Object

Programmierung und Angewandte Mathematik

Praxis der Programmierung

Transkript:

Strings, Aufteilung der Quelltexte, Vererbung, Polymorphie Institut für Informatik und Computational Science Universität Potsdam Henning Bordihn 1

Strings 2

C-Zeichenketten Arten von Zeichenketten char-array (also Pointer auf char) null-terminiert (letztes Element ist \0 ) String-Konstanten der Form "Hallo Text!" werden als C-Strings angelegt Klasse string der Standardbibliothek einfacherer Umgang mit Strings (keine Überläufe der Arraygröße, keine Nullterminierung) Objekt fordert nötigen Speicherplatz selbst an viele komfortable Methoden vordefiniert #include <string> using namespace std; string str; // Aufruf des Standardkonstruktors 3

Konstruktoren Die Klasse string Standardkonstruktor (ermöglicht spätere Initialisierung) Initialisierungskonstruktor mit einer String-Konstante als Parameter string(int n, char c) erzeut String aus n Zeichen c string name; name = "Programmer"; string ort("bithausen"); string trennlinie(60, - ); Kompatibilität zu C-Strings C-String string: per Zuweisung oder mit Initialisierungskonstruktor string C-String: Methode c str() konstanter char-pointer auf die Zeichenkette (unveränderlich!) mit strncpy() (<cstring>) in ein char-array überführen 4

Konstruktoren Die Klasse string Standardkonstruktor (ermöglicht spätere Initialisierung) Initialisierungskonstruktor mit einer String-Konstante als Parameter string(int n, char c) erzeut String aus n Zeichen c string name; name = "Programmer"; string ort("bithausen"); string trennlinie(60, - ); Kompatibilität zu C-Strings C-String string: per Zuweisung oder mit Initialisierungskonstruktor string C-String: Methode c str() der Klasse string konstanter char-pointer auf die Zeichenkette (unveränderlich!) mit strncpy() (<cstrin>) in ein char-array überführen 4

Beispiel Konvertieren in einen C-String #include <string> #include <cstring> using namespace std; int main() { string ort("potsdam"); const char *cstringpointer = ort.c_str(); } char veraenderlich[60]; strncpy(veraenderlich, cstringpointer, 60); veraenderlich[0] = p ; // ohne Probleme ort[1] = O ; // betrifft auch cstringpointer cstringpointer[1] = u // Compilerfehler 5

Einige Methoden der Klasse string (1) append(str) fügt str hinten an Alternative: s1 = s1 + s2; // auch s1 += s2; ist s1.append(s2); at(i) liefert Zeichen an Position i Alternative: str[i]; // ist str.at(i); clear() löscht alle Zeichen des Strings insert(p, str) fügt str an Position p ein erase(p, n) entfernt ab Position p n Zeichen replace(p, n, str) ersetzt ab Position p n Zeichen durch den String str 6

Einige Methoden der Klasse string (2) length() und size() liefern die Länge des Strings substr(p,n) liefert die Teilzeichenkette ab Position p der Länge n compare(str) vergleicht den String mit str empty() gibt true zurück, wenn der Sring leer ist weitere Methoden auf http://www.cplusplus.com/reference/ http://en.cppreference.com/w/cpp umfassende Dokumentationen der Klassen der Standardbibliothek 7

String-Iteratoren string-methoden begin() und end() liefern je ein Objekt vom Typ string::iterator Iteratoren sind Pointer, die string-objekte durchlaufen (Pointerarithmetik!) begin()-pointer zeigt auf erstes Zeichen des Strings end()-pointer zeigt hinter das letzte gültige Zeichen des Strings Vergleich mit dem end()-pointer zeigt an, dass das Stringende erreicht wurde symmetrisch : string::reverse iterator, rbegin(), rend() Gültigkeit nach Veränderung des Strings nicht mehr garantiert immer begin() unmittelbar vor Gebrauch des Iterators! 8

String-Iteratoren Beispiel #include <iostream> #include <string> using namespace std; int main() { string s = "Testlauf"; string::iterator i; for (i = s.begin(); i!= s.end(); i++) cout << *i; cout << endl; } 9

String-Vergleiche ohne Bibliotheksfunktionen möglich: == gleich!= ungleich < in lexikalischer Reihenfolge vorher > in lexikalischer Reihenfolge hinterher <= in lexikalischer Reihenfolge vorher oder gleich >= in lexikalischer Reihenfolge hinterher oder gleich 10

Umwandlung von oder in Zahlen Bibliothek sstream stellt Klassen istringstream und ostringstream bereit diese Klassen erlauben, Daten mit >> und << in bzw. aus Strings umzuleiten ostringstream stellt Methode str() zur Umwandlung des Streams in ein Exemplar der Klasse string zur Verfügung int zahl = 0; zahl = 3778; string s = "123"; ostringstream os; istringstream in(s); os << zahl; in >> zahl; // zahl = 123 s = os.str(); // s = "3778" 11

Aufteilung der Quelltexte 12

Leitgedanken bei der Quelltext-Aufteilung je Klassendefinition eine Datei Compiler-Aufruf zum Erzeugen der Objektdateien (.o) für jede beteiligte Datei einzeln möglich: g++ -Wall -c datei.cpp Linker wird aktiv bei Aufruf von g++ ohne Option oder mit Option -o alle beteiligten Dateien als Argumente übergeben (.cpp oder.o,.h) genau eine beteiligte Datei hat eine main-funktion es entsteht eine ausführbare Datei weitere Aufteilung einer Klasse in eine Header-Datei.h mit der Definition der Klasse, in der Datenelemente und Methoden nur deklariert werden eine.cpp-datei mit den Implementierungen der Methoden 13

Beispiel zur Quelltextaufteilung // date.h // highscore.h #include "date.h" class Date { class Highscore { int day, month, year; int score;... Date d; };... }; // date.cpp // highscore.cpp #include "date.h" #include "date.h"... #include "highscore.h"... > g++ date.cpp -c // liefert date.o > g++ highscore.cpp -c // Compilerfehler! (WARUM???) 14

Beispiel zur Quelltextaufteilung // date.h // highscore.h #include "date.h" class Date { class Highscore { int day, month, year; int score;... Date d; };... }; // date.cpp // highscore.cpp #include "date.h" #include "date.h"... #include "highscore.h"... > g++ date.cpp -c // liefert date.o > g++ highscore.cpp -c // Compilerfehler! (WARUM???) 15

Vermeiden von Doppel-Definitionen mit dem Präprozessor #ifndef _DATE_h #define _DATE_h class Date {... }; #endif // nur, falls die Variable _DATE_h nicht definiert ist // wird diese Konstante // und die Klasse Date definiert // sonst wird alles bis hier uebersprungen Analog: #ifndef _HIGHSCORE_h #define _HIGHSCORE_h class Highscore {... } #endif 16

Beispiel zur Quelltextaufteilung // date.h, implementiert in date.cpp // highscore.h, implementiert in highscore.cpp #ifndef _DATE_h #include "date.h" #define _DATE_h #ifndef _HIGHSCORE_h #define _HIGHSCORE_h class Date { class Highscore { int day, month, year; int score;... Date d; };... #endif }; #endif Applikation usehighscore.cpp (mit main) nutzt Highscore und Date: // usehighscore.cpp #include "date.h" #include "highscore.h"... > g++ date.cpp highscore.cpp usehighscore.cpp -o usehighscore 17

Klassenvariablen und -methoden 18

Klassenvariablen und -methoden werden mit dem Schlüsselwort static vereinbart sind der Klasse, nicht den Objekten zugeordnet; d.h. Klassenmethoden können auch aufgrufen werden, ohne dass ein Objekt der Klasse erzeugt wurde Klassenvariablen sind (mit ihren Werten) allen Exemplaren der Klasse gemeinsam, sind also klassenglobal Klassenvariablen werden vor dem ersten Exemplar der Klasse angelegt, müssen also wie globale Variablen definiert werden werden mit dem Klassennamen (statt mit dem Objektnamen) qualifiziert Klassenmethoden dürfen direkt nur auf Datenelemente und Methoden zugreifen, die ebenfalls static sind! 19

Beispiel Klassenvariablen class Static_Beispiel { int n; static int excounter; public: }; Static_Beispiel(int n) { this->n = n; excounter++; } ~Static_Beispiel() { excounter--; } void increase() { n++; } // wird im Speicher angelegt, // bevor das erste Objekt der Klasse erzeugt wird int Static_Beispiel::exCounter = 0; 20

Vererbung 21

Achsenparallele Quadrate in der Ebene (naiv) class Square { // Datenelemente int a; // Radius int x, y; // Koordinaten public: Square(int x, int y, int a); int getx(); int gety(); int getsize(); void moveto(int x, int y); void moverel(int dx, int dy); void resize(int a); double area(); // Flaeche berechnen }; 22

Kreise in der Ebene (naiv) class Circle { // Datenelemente int a; // Radius int x, y; // Koordinaten public: Circle(int x, int y, int a); int getx(); int gety(); int getsize(); void moveto(int x, int y); void moverel(int dx, int dy); void resize(int a); double area(); // Flaeche berechnen }; 23

WRITE ONCE! 24

Prinzipien bei der Vererbung Definition von Klassen (Unterklassen), die von einer anderen Klasse (Oberklasse) abgeleitet sind Vererbung aller Datenelemente und Methoden von der Oberklasse an jede ihrer Unterklassen Erweiterung der Oberklasse durch neue Datenelemente und Methoden möglich verdecken gleichnamige Elemente der Oberklasse Re-Definition (Überschreiben) geerbter Methoden (mit derselben Signatur!) können die Funktion der Oberklasse an geeigneter Stelle aufrufen: Oberklasse::verdeckteFunktion() hierarchische Vererbung (Kinder, Enkel, Urenkel,...) Mehrfachvererbung (Erben von mehreren Oberklassen gleichzeitig) 25

Definition einer Unterklasse class Unterklasse : public Oberklasse { // neue Datenelemente // ggf. Konstruktoren Unterklasse(...) { // ruft als erstes Oberklasse() auf... } // ggf. Destruktoren ~Unterklasse(...) { // ruft als letztes ~Oberklasse() auf... } }; // neue Methoden 26

Vererbung am Beispiel class Auto { public: void hupen() { cout << "huup" << endl; } }; int main() { class Pkw : public Auto { Auto karre; public: Pkw pkw; void aircondition() { karre.hupen() // "huup" cout << "fauch" << endl; pkw.hupen(); // "huup" } karre.aircondition(); // Fehler }; } 27

Überschreiben einer Funktion class Auto { public: void hupen() { cout << "huup" << endl; } }; int main() { class Pkw : public Auto { Auto karre; public: Pkw pkw; void hupen() { karre.hupen() // "huup" cout << "tuut" << endl; pkw.hupen(); // "tuut" } } }; 28

Konstruktoren bei der Vererbung Konstruktor der Unterklasse ruft zuerst einen Konstruktor der Oberklasse auf den Standardkonstruktor oder den explizit angegebenen Konstruktor Unterklasse(...) : Oberklasse(***) sorgt für Kompatibilität zur Oberklasse Exemplare der Unterklasse sind spezialisierte Exemplare der Oberklasse. Oberklasse allgemein; Unterklasse spezialisiert; allgemein = spezialisiert; spezialisiert = allgemein; // ok // geht nicht 29

Zugriffsattribute bei der Vererbung class Unterklasse : public Oberklasse alle Elemente (Datenelemente und Methoden) werden vererbt (auf private Elemente kann aber nicht direkt zugegriffen werden) class Unterklasse : Oberklasse oder class Unterklasse : private Oberklasse alle geerbten Elemente werden private Definition von Elementen mit protected: Zugriff nur für die Klasse und ihre Unterklassen 30

Zugriffsattribute Beispiel class Oberklasse { int main() { private: Oberklasse o; int privat; Unterklasse u; protected: int protect; int i = u.publik; // Fehler public: i = o.publik; // ok int publik; i = o.protect; // Fehler }; } class Unterklasse : Oberklasse { // privat! public: int f1() { return privat; } // geht nicht int f2() { return protect; } // ok int f3() { return publik; } // ok 31

Mehrfachvererbung Aufzählen der Oberklassen, durch Komma getrennt: class Unterklasse : public Elternklasse, public Superklasse {... } Vorsicht vor Namenskonflikten z.b. bei Datenelement var in beiden Oberklassen: a = Elternklasse::var; b = Superklasse::var; besser Mehrfachvererbung vermeiden! 32

Polymorphie durch Überschreiben virtueller Methoden Redifinieren ( Verdecken ) der Methode der Oberklasse bei Aufrufen wird die Imlementierung der Klasse abgearbeitet, die dem Typ entspricht, mit dem das Objekt definiert wurde Entscheidung durch den Compiler (statische/frühe Bindung) werden virtuelle Methoden (Schlüsselwort virtual) überschrieben, entscheidet der Typ des Objekts, an das der Aufruf gerichtet ist (dynamische/späte Bindung) Aber: bei Zuweisungen von Unterklassenobjekten an Oberklassenvariablen erfolgt automaisch eine Typkonversion Besonderheiten der Unterklasse gehen verloren! Pointer verwenden, um dynamische Bindung zu erreichen! 33

Polymorphie, nicht virtuell class Auto { void signal(auto * a) { public: a->hupen(); void hupen() { } cout << "huup" << endl; } }; class Pkw : public Auto { int main() { public: Auto karre; void hupen() { Pkw pkw; cout << "tuut" << endl; signal(&karre) // "huup" } signal(&pkw); // "huup" }; } 34

Polymorphie, virtuell class Auto { void signal(auto * a) { public: a->hupen(); virtual void hupen() { } cout << "huup" << endl; } }; class Pkw : public Auto { int main() { public: Auto karre; void hupen() { Pkw pkw; cout << "tuut" << endl; signal(&karre) // "huup" } signal(&pkw); // "tuut" }; } 35

Polymorphie, virtuell class Auto { void signal(auto * a) { public: a->hupen(); virtual void hupen() { } cout << "huup" << endl; } }; class Pkw : public Auto { int main() { public: Auto karre; void hupen() { Pkw pkw; cout << "tuut" << endl; signal(&karre) // "huup" } signal(&pkw); // "tuut" }; karre = pkw; // Typkonvertierung signal(&karre); // "huup" } 36