3. Exkurs in weitere Arten der Programmierung

Werbung
3. Exkurs in weitere Arten der Programmierung
Inhalt:
 Objektorientierte Programmierung in C++
 Logische Programmierung in Prolog
Peter Sobe
Objektorientierte Programmierung in C++
C++ ist eine objektorientierte Erweiterung der Sprache C
Neu gegenüber C: Klassen und Objekte
Klassen:
 Geben die Anordnung der Daten vor (vgl. struct)
 Enthalten Funktionen zur Initialisierung und zum Umgang
mit den Daten
 Ergeben jeweils einen neuen Typ
Objekte:
 Sind Variablen eines Klassentyps
Peter Sobe
2
Aufbau einer Klassendeklaration in C++
Aufbau einer Klasse in C++ :
class name
{
private:
Deklaration der Datenelemente
public:
};
R.Grossmann / P. Sobe
Definition
der Methoden
3
Deklaration der Datenelemente
Beispiel Klasse vektor
Der Teil Deklaration der Datenelemente wird gemäß der Kapselung mit
dem Zugriffsspezifizierer private eingeleitet. Dies wird bei Weglassen auch
automatisch angenommen.
Beispiel:
class vektor
{
private: float x, float y, float z; //Dekl. Datenelemente
public: .......
}
Ein Vektor des R³ hat drei Komponenten als Datenelemente.
Der Typ der Elemente ist hier float.
R.Grossmann / P. Sobe
4
Deklaration der Datenelemente
Allgemein dürfen zur Deklaration von Datenelementen alle in
C/C++ bekannten Standardtypen (auch Zeiger, Felder,
Strukturen usw. benutzt werden. Sind neue Typen über
Klassen definiert, dürfen diese Typen dann auch zur
Deklaration von Datenelementen anderer Klassen verwendet
werden.
Die Datenelemente einer Klasse bezeichnet man auch als
Elementobjekte (auch engl. Member). Da eine Klasse einen
eigenen Gültigkeitsbereich für Namen bildet, sind
Datenelemente lokal bezüglich der Klasse und nur Methoden
der Klasse können Zugriffe auf diese auslösen.
R.Grossmann / P. Sobe
5
Klassendeklaration
Innerhalb einer Klasse darf niemals eine weitere
Klassendeklaration vorgenommen werden.
Richtig:
Falsch:
class ABC {
class ABC {
};
class XYZ {
class XYZ {
};
};
};
int main() { … }
int main() { … }
P. Sobe
6
Deklaration / Definition / Aufruf von Methoden
Methoden sind einer Klasse zugeordnet und bilden die Menge der
Operationen, die mit den Objekten der Klasse ausführbar sind.
Damit der Nutzer Methoden zur Manipulation der Objekte in seinem
Anwendungsprogramm aufrufen kann, müssen diese in aller Regel
in einem public-Teil verfügbar sein.
Methoden sind – syntaktisch gesehen - Funktionen im Sinne von
C/C++. Die Deklaration und Definition der Methoden genügt den
Regeln für normale Funktionen.
Durch die Bindung an die Klasse unterscheidet sich der Aufruf von
Methoden gegenüber normalen Funktionen:
normale Funktion f(x) Methode f(x) der Klasse T
f(y);
T a;
a.f(y);
R.Grossmann / P. Sobe
7
Definition von Methoden am
Beispiel der Klasse vektor
Definition von Inline-Methoden:
class vektor
{ private: float x, float y, float z; //Dekl. Datenelemente
public: void init(float i,float j,float k) { x=i; y=j; z=k;}
float betrag(){return sqrt(x*x+y*y+z*z);}
______________________________________________
Gewöhnliche Trennung von Deklaration und Implementierung:
class vektor
{ private: float x, float y, float z; //Dekl. Datenelemente
public: void init(float i,float j,float k) ;
float betrag(); .....
};
void vektor::init (float i,float j,float k) { x=i; y=j; z=k;}
float vektor::betrag(){return sqrt(x*x+y*y+z*z);}
R.Grossmann / P. Sobe
8
Inline-Definition von Elementfunktionen
Beispiel Klasse vektor
Code-Beispiele:
oo_vektor1.cpp – Deklaration und Definition der
Elementfunktionen zusammen.
oo_vektor2.cpp – getrennte Deklaration und Definition.
In größeren Softwareprojekten werden die Klassendeklarationen in
Header-Dateien (*.h) vorgenommen. Die Methoden der Klasse
werden getrennt in *.cpp-Dateien implementiert.
R.Grossmann / P. Sobe
9
Konstruktor und Destruktor
- obligatorische Methoden einer Klasse
Damit eine ordnungsgemäße Arbeit mit Objekten einer Klasse
möglich wird, z.B. Erzeugung, Zerstörung von Objekten, müssen
einige spezielle Methoden immer definiert sein.
Wenn Sie vom Programmierer nicht angegeben werden, so werden
sie standardmäßig vom C++-Übersetzer erzeugt:
 mindestens ein Konstruktor zur Erzeugung (Instanziierung)
eines Objektes. In C++ muss ein Konstruktor den Klassennamen als Funktionsnamen tragen, ohne die Angabe eines
Funktionstyps (auch nicht void)
vektor(float i,float j,float k) {....}
Beispiel:
Der leere Konstruktor wird (falls nicht angegeben) vom
Übersetzer automatisch erzeugt (engl. Default Constructor)
Beispiel: vektor(){}
R.Grossmann / P. Sobe
10
Destruktor
 genau ein Destruktor zur Zerstörung (Freigabe) eines
Objektes. In C++ muss der Destruktor den Klassennamen als
Funktionsnamen mit einer vorangestellten Tilde tragen;
er muss parameterlos sein.
Beispiel:
~ vektor() {....}
Wird der Destruktor vom Programmierer nicht angegeben, so
wird ein leerer Standard-Destruktor angenommen.
R.Grossmann / P. Sobe
11
Der Standard-Konstruktor einer Klasse
Als Standard-Konstruktor einer Klasse wird ein Konstruktor
bezeichnet, der parameterlos ist. Es kann deshalb nur einen
Standard-Konstruktor geben.
Wird vom Programmierer kein Konstruktor in der Klasse
angegeben, dann erzeugt der Compiler diesen Default-StandardKonstruktor.
Ein Standard-Konstruktor wird immer gebraucht, wenn ein Feld von
Elementen der Klasse deklariert werden soll, z.B.
vektor matrix[10];
matrix ist ein Feld mit 10 Vektoren.
R.Grossmann / P. Sobe
12
Weitere Methoden der Klasse vektor
vektor add(vektor a) { return vektor(x+a.x,y+a.y,z+a.z); }
vektor sub(vektor a) { return vektor(x-a.x,y-a.y,z-a.z); }
float mult(vektor a) { return x*a.x+y*a.y+z*a.z; }
vektor kreuz(vektor a)
{ return vektor(y*a.z-z*a.y, z*a.x-x*a.z, x*a.y-y*a.x); }
Jetzt kann man dieser Operationen in der Anwendung auf vektorObjekte anwenden:
neu=a.add(c);
//Addition
neu=n.sub(a);
//Subtraktion
cout<<"\nSkalarprodukt="<< b.mult(c); //Skalarprodukt
neu=b.kreuz(c); neu.drucke();
R.Grossmann / P. Sobe
//Kreuzprodukt
13
Weitere Methoden der Klasse vektor
Besonders wichtig ist, dass die Implementierungen der Funktionen
einen vektor-Wert als Rückgabewert zurückgeben, z.B.:
vektor add(vektor a) {return vektor(x+a.x,y+a.y,z+a.z);}
Dadurch kann man fortlaufende Operationen kodieren, wie
z.B. neu=n.add(a).add(b).sub(d);
Hätte man add als void-Funktion implementiert, wäre das in dieser
Weise nicht möglich gewesen.
R.Grossmann / P. Sobe
14
Reihung (Felder) von Objekten
Besitzt eine Klassendefinition einen Standard-Konstruktor
(Konstruktor ohne Parameter), so können im Programm auch
Felder mit Elementen dieses Typs deklariert werden.
Beispiel:
class vektor
{ private: float x,y,z ;
public: vektor(){ }
// Standardkonstruktor
vektor(float ax,float ay,float az) {x=ax;y=ay;z=az; }
.....
};
Im C++-Programm können jetzt Felder von Vektoren vereinbart
werden:
vektor vfeld[20];
vektor fv[4] = { v1, v2, v3, v4}; // v1-v4 sind Vektor-Objekte
R.Grossmann, P. Sobe
15
Prinzip der Stapel-Datenstruktur
Eine wichtige Datenstruktur
ist
der
s.g.
Stapel
(engl. Stack).
Er arbeitet nach dem LIFOPrinzip, Last in – First out.
Die Implementation stellt den
Stack als ein auf dem
Speicher gereihtes Feld von
Elementen
dar,
welche
zunächst als vom Typ int
angenommen werden.
Index Element
Position des
nächsten zu
speichernden
Elementes
...
n
n-1 302
... ...
1
7
0 49
R.Grossmann, P. Sobe
top
Nur das top-Element
kann entfernt werden
(pop)
bottom
16
Beispiel Klasse stack / Klassendefinition
class stack
{ private:
int *st; int p;
public:
stack(int m=100) {st = new int[m]; p=0;}
~stack() { delete [] st;}
void push(int v) {st[p++]= v; }
int pop() {return st[--p];}
int empty() {return !p;}
};
Der Elementtyp für die stack-Elemente ist int .
R.Grossmann, P. Sobe
17
typedef – Anweisung am Beispiel der Klasse stack
Die Struktur und Arbeit mit dem stack hängt nicht vom Elementtyp
für die stack-Elemente ab, d.h. das gleiche Prinzip würde auch für
Elemente vom Typ char oder complex gelten.
Deshalb wird ein eigener Typ eingeführt (per typedef-Anweisung), den
man flexibel mit verschiedenen Basisdatentypen oder eigenen
Strukturen verbinden kann.
typedef char item ; // konkreter Typ wird festgelegt
class stack
{ private: item *st; int p;
public: stack(int m=100) {st = new item[m]; p=0;}
~stack() { delete [] st;}
void push(item v) {st[p++]= v; }
item pop() {return st[--p];}
int empty() {return !p;}
};
R.Grossmann, P. Sobe
18
Herunterladen