oop und angewandte mathematik - gm.fh-koeln.deafomusoe/ws2011_12/lecture07_2011_12.pdf · templates...
Post on 14-Aug-2019
218 Views
Preview:
TRANSCRIPT
OOP und Angewandte Mathematik
Eine Einführung in die Anwendungobjektorientierter Konzepte in derj p
angewandten Mathematik
WS 2011/12WS 2011/12
Inhalt
Templates Nochmal zusammengefasstg
Die Basis der OOP- Zusammengefasst
OOP und Angewandte Mathematik2
Fomuso Ekellem
Templates
Programmiersprachen sollten elegante Mechanismen besitzen, um Redundanz beim Programmieren vermeiden zu können.
Angenommen, wir wollen Listen-, Array, oder Matrizen-Klassen implementieren, die verschiedene Datentypen als Inhalt aufnehmen können(z.B. int, double, bool, usw…). Alle Operationen bleiben gleich:) p g
1 2 3 1.3 2.5 4.3 true false true4 5 6 3.4 5.2 6.3 true true true7 8 9 1 2 4 5 7 2 false true false7 8 9 1.2 4.5 7.2 false true false
In C++ wird dieses Konzept “Template” genannt. Eine andere Bezeichnung (z.B. in Java 1.5) ist “Generic”.
OOP und Angewandte Mathematik3
Fomuso Ekellem
Templates
Motivation: Eine Klasse erstellen für verschiedene Datentypen Datenrepräsentation: Matrix, Stacks, Listen, Bäume...p
Code für einen Datentyp sollte für kompatible Typen wieder verwendbar sein. C++ bietet die Möglichkeit, mit Hilfe von Templates (Schablonen, Vorlagen) eine
parametrisierte Familie verwandter Funktionen oder Klasse zu definierenparametrisierte Familie verwandter Funktionen oder Klasse zu definieren Funktions-Templates legen die Anweisung einer Funktion fest, wobei statt eines
konkreten Typs ein Parameter T gesetzt wird Klassen-Templates legen die Definition einer Klasse fest, wobei statt eines Typs ein Klassen Templates legen die Definition einer Klasse fest, wobei statt eines Typs ein
Parameter T eingesetzt wird.
Vorteile Ein Template muss nur einmal codiert werden Einzelne Klassen oder Funktionen Ein Template muss nur einmal codiert werden. Einzelne Klassen oder Funktionen
werden automatisch erzeugt. Einheitliche Lösung für gleichartige Probleme, wobei man unabhängige Bestandteile
frühzeitig testen kann
OOP und Angewandte Mathematik4
Fomuso Ekellem
Templates
Funktions-Templates Beispiel: swap()-Funktionp p() Verhalten ist für jeden Typ gleich (elementar und andere) Ineffizient: schreibe für jeden Typ eine eigene überladene Funktion
Lö d fi i i S h bl fü di F kti Lösung: definiere eine Schablone für die Funktionswap() für Typ <int> swap() für beliebigen Typ <T>
void swap (int& a, int& b) {template <class T>
void swap (int& a, int& b) {int tmp = a;a = b;b = tmp;}
void swap (T& a, T& b) {T tmp = a;a = b;b = tmp;}}
OOP und Angewandte Mathematik5
Fomuso Ekellem
Templates
Die template <...> Zeile sagtEin Template erwartet alsdem Compiler: „die folgende
Deklaration o. Definition ist alsSchablone zu verwenden“.
Ein Template erwartet alsArgumente Platzhalter fürTypen: Template-Parameter
template <class T>void swap (T& a, T& b) {T tmp = a;T tmp a;a = b;b = tmp;}
Die Platzhalter innerhalb des Template werden später (noch vor der Übersetzung in Maschinensprache) durch spezifische Typen ersetzt
OOP und Angewandte Mathematik6
Fomuso Ekellem
Templates
Templates sollen den Aufwand für den Entwickler reduzieren: Templates werden vom Kompiler nach Bedarf in eine normale Funktion/Klasse p p
gewandelt. Wird swap für 2 int-Werte verwendet, so wird eine weitere Funktion erzeugt. Wird swap für 2 Auto-Werte verwendet, so wird eine weitere Funktion erzeugt. Beim Kompilieren findet auch die Typprüfung statt.
Syntax für explizite Spezialisierung
double d1 = 4.0, d2 = 2.0;swap<double>(d1, d2);
Explizit bedeutet: der Programmierer spezifiziert ausdrücklich, mit welchem Typ die Templateparameter zu ersetzen sind.
OOP und Angewandte Mathematik7
Fomuso Ekellem
Templates
Implizite Spezialisierung
double d1 = 4.0, d2 = 2.0;//Alles klar: T = doubleswap(d1, d2);
double d1 = 4.0;float f1 = 10.0f;swap(d1, f1);
Das geht nicht ! Compiler meldet:no matching function for call to´swap(double&, float&)´
Entweder
swap<double>(d1, f1); Implizite Typkonvertierung von <f1>
Oder
swap(d1, double(f1)); Explizite Typkonvertierung von <f1>
OOP und Angewandte Mathematik8
Fomuso Ekellem
Templates
In vielen Anwendungen ist es nicht nur notwendig eine Funktion, sondern eine ganze Klasse mit einem Typ zu parametrisieren. Z.B.: Implementierung von elementaren Datenstrukturen wie Stack, Queue, binäre
Suchbäume,usw. Stack Beispiel
template <class T>class Stack {
private:T* inhalt // Datenbereich des StacksT* inhalt; // Datenbereich des Stacksint index, size; // Aktueller Index, Grösse des Stackspublic:Stack(int s): index(-1), size(s) { // Constructorinhalt = new T[size]; // Stack als Array implementiert}}void push(T item) { // Ein Element auf den Stack "pushen"if (index < (size - 1)) {inhalt[++index] = item;}}}T top() const { // Ein Element vom Stack lesenif (index >= 0) {return inhalt[index];}}void pop() { // Ein Element auf dem Stack löschenif (index >= 0) {--index;}
OOP und Angewandte Mathematik9
Fomuso Ekellem
if (index 0) { index;}}
};
Templates
Gebrauch der Template-Klasse Stack
int main() {Stack<int> intStack(100); // Stack für 100 intStack<double> doubleStack(250); // Stack für 250 doubleStack<rect> rectStack(50); // Stack für 50 rectintStack push(7);intStack.push(7);doubleStack.push(3.14);rectStack.push(rect(2,5));}
Bei der Allozierung eines Stacks muss explizit der Typ angegeben werden(<int>, <rect>, ...)
Auch hier gilt: die entsprechende Klasse wird vom Compiler bei Bedarf aus der Auc e g lt: d e e tsp ec e de lasse w d vo Co p le be Beda f aus de Template-Klasse generiert.
OOP und Angewandte Mathematik10
Fomuso Ekellem
Templates
Nochmals die Template-Klasse Stack, diesmal aber mit Trennung von Deklaration und Definition: Definition: stack.cppHeader-Datei: stack.h
template <class T>class Stack {
#include "stack.h"using namespace std;// Achtung: nicht Stack::Stack(int s)!template <class T>Stack<T>::Stack(int s):index( 1) size(s){
private:T* inhalt;int index;int size;
public:
Stack<T>::Stack(int s):index(-1),size(s){inhalt = new T[size];}template <class T>
public:Stack(int s);void push(Type item);T top() const;void pop();
}
void Stack<T>::push(T item) {if(index<size) {inhalt[++index]=item;}}template <class T>T Stack<T>::top() const {
};p() {
if (index>=0) {return inhalt[index];}}template <class T>void Stack<Type>::pop() {if (index >= 0) {index--;}
OOP und Angewandte Mathematik11
Fomuso Ekellem
if (index >= 0) {index--;}}
Templates
Gebrauch!!!
#i l d " k "#include "stack.cpp"using namespace std;int main() {Stack<int> intStack(100);Stack<double> doubleStack(250);intStack.push(7);doubleStack.push(3.14);}
Man beachte: stack.cpp, nicht stack.h!!! Bei Templates muss die komplette Implementierung eingebunden werden, weil
der Compiler die Klasse bei Bedarf erzeugt (Spezifikation allein reicht also nicht)de Co p le d e lasse be Beda f e eugt (Spe f at o alle e c t also c t) Dies gilt auch für Template Funktionen; Die Funktionsdeklaration allein reicht
nicht.
OOP und Angewandte Mathematik12
Fomuso Ekellem
Templates
Die Angabe des Datentyps beim Gebrauch eines Templates bestimmt, wofür eine Instanz des Templates gebraucht werden kann:
Ausnahme: auch Subklassen von Person können auf diesem Stack abgelegt werden.
Stack<Person> personStack(100); // Nur für Typ Person verwendbar
werden. Dabei werden die Objekte aber in Person konvertiert...
wodurch die in Subklassen spezifizierte Funktionalität (und damit auch Polymorphismus) verloren gehtPolymorphismus) verloren geht.
Besser: man verwendet einen Zeiger auf die Basisklasse:
l l h l d
Stack<Person*> personStack(100); // Für alle verwendbar
Vorteile: Polymorphismus funktioniert; Subklassen von Person können auf dem Stack abgelegt werden, ohne deren zusätzliche Information zu verlieren.
OOP und Angewandte Mathematik13
Fomuso Ekellem
Templates
Templates von Templates: Templates können als Parameter für andere Templates dienen:
complex<float> c1, c2;swap<complex<float> >(c1, c2);
complex<T> ist eine Klasse der C++ Standard Bibl. für Komplexe Zahlen (#include <complex>)A h B i h h l T l f i d f l d ‘ ‘ d h Achtung: Bei geschachtelten Templates muss man aufeinander folgende ‘>‘ durch Leerzeichen trennen, da sie sonst als shift-Operator missinterpretiert werden.
OOP und Angewandte Mathematik14
Fomuso Ekellem
Templates
Ein Template existiert nicht als Typ oder Objekt. Erst bei Instanziierung eines Template entsteht eine neuer Typ g p yp
(Funktion/Klasse) bei dem die Template-Parameter durch konkrete Typen ersetzt wurden.
Ohne Templates: Ohne Templates: werden Interface und Implementierung in separaten Dateien untergebracht (.h, .cpp) stellt der Linker die Verbindung zwischen dem Aufruf einer deklarierten Methode und
dem zusätzlichen Maschinen-Code her.
Mit Templates: wird Code erst bei Bedarf generiert. Bedarf heißt, z.B. durch Bindung an spezifische
Template-ParameterTemplate Parameter kann nur der vom Template generierte Code übersetzt und gelinkt werden.
OOP und Angewandte Mathematik15
Fomuso Ekellem
Klassen und Strukturen in C++
Die Basis der OOP- Zusammengefasst C++ erlaubt unter anderen die Deklaration von Klassen und Strukturen zur
Strukturierung eines OOP-Programms. Klassen und Strukturen unterscheiden sich in C++ prinzipiell kaum. In beiden
können Sie Eigenschaften und Methoden unterbringen.können Sie Eigenschaften und Methoden unterbringen. Klassen werden mit dem Schlüsselwort class deklariert, Strukturen mit struct. Alle Datenfelder in einer Struktur sind öffentlich. Klassen ermöglichen dagegen,
dass Datenfelder privat oder geschützt (protected) deklariert werden Strukturen dass Datenfelder privat oder geschützt (protected) deklariert werden. Strukturen ermöglichen somit nicht das wichtige Konzept der Kapselung.
class person{string Name; // private
struct person{string Name; // public
g pstring Nachname //private
public:void laufen(){ //public}
};
string Name; // publicstring Nachname //publicvoid laufen(){ //public}
};
OOP und Angewandte Mathematik16
Fomuso Ekellem
};
Klassen und Strukturen in C++
Strukturen können nur wie einfache Klassen behandelt werden, damit die Umsetzung von C-Quellcode nach C++ vereinfacht wird. Da die Strukturen die wichtige Kapselung nicht unterstützen, sollten Sie stattdessen immer Klassen einsetzen.
In dieser Vorlesung wird class immer benutzt!g
OOP und Angewandte Mathematik17
Fomuso Ekellem
Die Strukturierung einer Anwendung
Größere Programme erfordern eine Strukturierung des Quellcodes. Die Basis der Strukturierung ist in C++ eine Klasse.
Über Klassen erreichen Sie, dass Sie Programmcode wiederverwenden können und dass Sie Ihr Programm so strukturieren, dass die Fehlersuche und die Wartung erheblich erleichtert werden.g
Wenn Sie eine Klasse entwickeln, können Sie entscheiden, ob Sie eine echteKlasse (mit normalen Eigenschaften und Methoden) programmieren, aus der Sie später Instanzen erzeugen, oder ob Sie eine Klasse mit statischen Methoden und p g ,Eigenschaften erzeugen wollen.
Statische Methoden und Eigenschaften (Klassenmethoden, Klasseneigenschaften) können Sie auch ohne eine Instanz der Klasse aufrufen. ö e S e auc o e e e sta de lasse auf ufe .
Echte Klassen arbeiten echt objektorientiert, Klassen mit statischen Methoden und Eigenschaften simulieren (u. a.) die Module der strukturierten Programmierung.Programmierung.
OOP und Angewandte Mathematik18
Fomuso Ekellem
Einfache Klassen und deren Anwendung
Grundlagen zur Programmierung von Klassen In einer C++-Datei (mit der Endung .cpp oder .cc) können Sie eine oder mehrere ( g pp )
Klassen implementieren. Sie können Klassen komplett in der cpp-Datei unterbringen und auf eine
Headerdatei verzichten oderHeaderdatei verzichten oder In h-Datei und cpp-Datei trennen. Die h-Datei (Headerdatei) enthält die
Deklaration der Klasse, die cpp-Datei enthält die Implementierung der Methoden der Klasseder Klasse.
In einer cpp-Datei können Sie eine oder mehrere Klassen unterbringen. In der Praxis werden Klassen oft in separaten Dateien deklariert, um diese einfach
i d P i d d köin anderen Programmen wiederverwenden zu können. Diese Trennung macht auch dann Sinn, wenn Sie Ihre Klassen in Bibliotheken
(mit der Endung .lib) kompilieren und diese Bibliotheken für die eigene V d i i O d i hVerwendung in einem separaten Ordner speichern.
OOP und Angewandte Mathematik19
Fomuso Ekellem
Einfache Klassen und deren Anwendung
Objekte statisch erzeugen Statisch erzeugen Sie ein Objekt, indem Sie eine Objektvariable wie eine einfache g j , j
Variable deklarieren:
Statisch bedeutet hier dass C++ das Objekt auf dem Stack speichert Der Stack ist
Kreis k; // statische Erzeugung
Statisch bedeutet hier, dass C++ das Objekt auf dem Stack speichert. Der Stack ist ein Speicherbereich, den alle Programme besitzen und auf dem u. A. alle lokalen Variablen einer Funktion oder Methode gespeichert werden.
Da der Stack nach der Ausführung der Funktion/Methode wieder automatisch Da der Stack nach der Ausführung der Funktion/Methode wieder automatisch bereinigt wird, werden statische Objekte also automatisch zerstört, wenn die Funktion bzw. Methode beendet ist.
Ei P bl b i t ti h Obj kt i t d Obj kt kö t ß i d Ein Problem bei statischen Objekten ist, das Objekt könnte zu groß sein, und man muss bei der Entwicklung immer beachten wie viele Objekt erzeugt werden müssen.
OOP und Angewandte Mathematik20
Fomuso Ekellem
Einfache Klassen und deren Anwendung
Objekte dynamisch erzeugen Für die dynamische Erzeugung von Objekten deklarieren Sie die Objektvariable y g g j j
als Zeiger:
Dann erzeugen Sie das Objekt über den new Operator:
Kreis * k; // dynamische Erzeugung
Dann erzeugen Sie das Objekt über den new-Operator:
Dynamisch erzeugte Objekte werden auf dem Heap angelegt. Der Heap ist ein S i h b i h d f l b l D i i A f d H d
Kreis = new Kreis
Speicherbereich, der für globale Daten reserviert ist. Auf dem Heap werden außerdem alle Funktionen und Klassen einer Anwendung gespeichert. Die Größe des Heap ist nur durch den im System verfügbaren Speicher begrenzt.
So kann Ihre Anwendung während des Programmablaufs (eben dynamisch) nahezu beliebig viele Objekte erzeugen.
OOP und Angewandte Mathematik21
Fomuso Ekellem
Einfache Klassen und deren Anwendung
Objekte dynamisch erzeugen Objekte, die dynamisch erzeugt wurden, können über eine Dereferenzierung des j , y g , g
Zeigers angesprochen werden:
Durchgesetzt hat sich aber die Kurzschreibweise die mit dem Operator >
(*k). Radius = 20
Durchgesetzt hat sich aber die Kurzschreibweise, die mit dem Operator -> arbeitet:
D i h Obj k Si i ll d i h i
k->Radius = 20
Dynamisch erzeugt Objekte müssen Sie wie alle dynamisch reservierten Speicherbereiche über die delete-Anweisung aus dem Speicher entfernen.
delete k;
Vergessen Sie dies, bleibt das Objekt im Speicher, so lange Ihre Anwendung läuft, und verbraucht unnötig Ressourcen.
OOP und Angewandte Mathematik22
Fomuso Ekellem
Einfache Klassen und deren Anwendung
Die Bedeutung des Stack Der Stack ist ein spezieller Speicherbereich, den jedes Programm besitzt und der p p , j g
wie ein Stapel arbeitet: Daten werden der Reihe nach auf dem Stapel abgelegt und können auch wieder, der Reihe nach, vom Stapel entfernt werden. (Last in firstout-LIFO))
Der Stack wird vom Compiler automatisch über Funktionen angesprochen, die Daten auf dem Stapel ablegen, Daten vom Stapel auslesen und vom Stapel löschen. p
OOP und Angewandte Mathematik23
Fomuso Ekellem
Einfache Klassen und deren Anwendung
Die Bedeutung des Stack : Beispiel
Beim Aufruf der Funktion Add int Add(int x, int y){
int result;result = x + y;
Beim Aufruf der Funktion Add, legt der Compiler die folgenden Daten auf dem Stack an:1. einen Speicherbereich für
den Rückgabewert der return result;}
void main(void){
den Rückgabewert der Funktion,
2. die Adresse, zu der das Programm nach der Ausführung zurückspringen {
int i = Add(1, 2);cout << I;
}
Ausführung zurückspringen muss,
3. die Argumente der Funktion,4. und die lokalen Variablen der
F k iFunktion.
OOP und Angewandte Mathematik24
Fomuso Ekellem
Einfache Klassen und deren Anwendung
Wie werden Objekte gespeichert? Um zu verstehen wie z.B den Polymorphismus und virtuellen Methoden
funktionieren, müssen Sie wissen wie, Objekte prinzipiell gespeichert werden. Eine Instanz einer Klasse besteht prinzipiell nur aus den Datenfeldern der Klasse
(außer, wenn die Klasse Inline-Methoden beinhaltet, die innerhalb der Instanz (gespeichert werden).
Beispielclass Punkt
class Kreis{public:
int x;int y;void set(int x, int y)
class Kreis{public:
int Radius;int Farbe;d bl U f
( , y){
this->x = x;this->y = y;
}};
double Umfang{
return Radius * 2 * 3.1415927;}
};
OOP und Angewandte Mathematik25
Fomuso Ekellem
};
Einfache Klassen und deren Anwendung
Wie werden Objekte gespeichert?
void main(void){
Kreis k1;Kreis k2;P kt 1Punkt p1;
k1.Radius = 100;k1.Farbe = 255;k2.Radius = 200;k2.Farbe = 1024;
p1.Set(10, 11);}
k1, k2 und p1 sind also Variablen, die auf die Adresse zeigen, an der die Eigenschaften des Objekts gespeichert sind. Dieses Vorgehen reduziert den Speicherbedarf von Objekten enorm
OOP und Angewandte Mathematik26
Fomuso Ekellem
Speicherbedarf von Objekten enorm.
Einfache Klassen und deren Anwendung
Der this-Zeiger Damit eine Methode, die ja normalerweise (wenn es keine Inline-Methode ist), die
Eigenschaften der aufrufenden Instanz bearbeiten kann, übergibt der Compiler der Methode ein zusätzliches, unsichtbares Argument, den this->Zeiger.
double Umfang(Kreis *this){
return this->Radius * 2 * 3.1415927;}
Dieser Zeiger zeigt auf die Objektinstanz, von der aus der Aufruf erfolgt ist. Wenn Sie in einer Methode auf Eigenschaften oder Datenfelder des Objekts zugreifen oder
andere Methoden aufrufen, stellt der Compiler diesen Zeiger implizit vor den Namen des verwendeten Klassenelements, falls dies noch nicht explizit geschehen ist und falls ein entsprechendes Klassenelement gefunden wird. Siehe nächste Folie...
OOP und Angewandte Mathematik27
Fomuso Ekellem
Einfache Klassen und deren Anwendung
Konkretes this-> Beispiel
class Kreis{public:
main:
Kreis k1 // Statisch deklariertK1 als Objekt hat Radius und Farbe als Eigenschaften und kann Umfang (Methode)aufrufen Implizit sieht im kompilierten public:
int Radius;int Farbe;double Umfang{
t R di * 2 * 3 1415927
g ( ) p pProgrammcode demnach so aus, falls noch nicht so definiert ist
double Umfang(Kreis *this){
return this->Radius * 2 * 3 1415927;return Radius * 2 * 3.1415927;}
};
return this->Radius 2 3.1415927;}
K1 (ist Aufrufer)
this ist der der zu eine gegebene Zeit eine Funktion Ausführt
OOP und Angewandte Mathematik28
Fomuso Ekellem
Die Basis der OOP- Zusammengefasst
Die Sichtbarkeit von Klassenelementen Daten schützen: Die Kapselung p g
Die klassische Kapselung Bessere Kapselung mit Ausnahmen
Konstruktoren und Destruktoren Konstruktoren und Destruktoren Konstruktoren Der Copy-Konstruktor Der Destruktor Der Destruktor
Assoziationen zwischen Objekten
OOP und Angewandte Mathematik30
Fomuso Ekellem
Die Basis der OOP- Zusammengefasst
Vererbung Warum Vererbung? g Das Beispiel Die Grundlagen der Vererbung
Di N d fi iti M th d Die Neudefinition von Methoden Verwenden geerbter Elemente Die Sichtbarkeit bei der Vererbung Veröffentlichen von privaten und geschützten Elementen in abgeleiteten Klassen Vererbung von Konstruktoren und Destruktoren Polymorphismus und virtuelle Methoden Polymorphismus und virtuelle Methoden public-, protected- und private-Ableitung Mehrfachvererbung
OOP und Angewandte Mathematik31
Fomuso Ekellem
top related