8. Objektorientierung und C++



Ähnliche Dokumente
Vorkurs C++ Programmierung

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

4. Objektorientierte Programmierung mit C++

Überblick. R.Grossmann / P. Sobe 1

Überblick. 5. Objekt und Klasse, Elementfunktionen

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Einführung in die Java- Programmierung

Objektorientierte Programmierung OOP

Objektorientierte Programmierung

Objektorientierte Programmierung für Anfänger am Beispiel PHP

Programmieren in Java

5. Abstrakte Klassen. Beispiel (3) Abstrakte Klasse. Beispiel (2) Angenommen, wir wollen die folgende Klassenhierarchie implementieren:

Software Engineering Klassendiagramme Assoziationen

Klassendiagramm. Kurzer Überblick über UML - Stand BlaBla

Fachdidaktik der Informatik Jörg Depner, Kathrin Gaißer

Grundlagen der Informatik Vererbung von Klassen

Unterprogramme. Funktionen. Bedeutung von Funktionen in C++ Definition einer Funktion. Definition einer Prozedur

4. Objektorientierte Programmierung mit C++

Zählen von Objekten einer bestimmten Klasse

3. Konzepte der objektorientierten Programmierung

Software Engineering Klassendiagramme Einführung

5. Abstrakte Klassen

Arbeiten mit UMLed und Delphi

Objektorientierte Programmierung mit C++ Zusammenfassung der wichtigsten Topics rund um die objektorientierte Programmierung mit C++11

EinfÅhrung in die objektorientiere Programmierung (OOP) unter Delphi 6.0. EDV Kurs 13/2

Softwaretechnik (Allgemeine Informatik) Überblick

Java Kurs für Anfänger Einheit 5 Methoden

2. Programmierung in C

Objektorientierte Programmierung. Kapitel 12: Interfaces

Stellen Sie bitte den Cursor in die Spalte B2 und rufen die Funktion Sverweis auf. Es öffnet sich folgendes Dialogfenster

Java Kurs für Anfänger Einheit 4 Klassen und Objekte

Einführung in die objektorientierte Programmierung mit Java. Klausur am 19. Oktober 2005

GetName(), GetName(), GetGeschlecht() und AelterWerden().

Einführung in die Programmierung

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

Objektbasierte Entwicklung

3 Objektorientierte Konzepte in Java

Grundlagen von Python

Klassenbeziehungen & Vererbung

SEP 114. Design by Contract

Bedienung von BlueJ. Klassenanzeige

Deklarationen in C. Prof. Dr. Margarita Esponda

Java: Vererbung. Teil 3: super()

SWE5 Übungen zu Software-Engineering

OO Softwareentwicklung

Objektorientierte Programmierung

1 Mathematische Grundlagen

Programmieren I. Strategie zum Entwurf von Klassen. Beispiele. Design von Klassen. Dr. Klaus Höppner. Beispiel: Bibliothek

Programmieren II Vererbung. Programmieren II Vererbung. Programmieren II Vererbung. Programmieren II Vererbung. Einleitende Bemerkungen

4 Vererbung, Polymorphie

Software Engineering Interaktionsdiagramme

Prinzipien Objektorientierter Programmierung

Vererbung & Schnittstellen in C#

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

Erstellen einer digitalen Signatur für Adobe-Formulare

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

Überblick. 6. Konstruktor und Destruktor - obligatorische Elementfunktionen einer Klasse

Von der UML nach C++

Der Aufruf von DM_in_Euro 1.40 sollte die Ausgabe 1.40 DM = Euro ergeben.

Kapitel 6. Vererbung

Pass by Value Pass by Reference Defaults, Overloading, variable Parameteranzahl

Kapitel 6. Vererbung

Ziel, Inhalt. Programmieren in C++ Wir lernen wie man Funktionen oder Klassen einmal schreibt, so dass sie für verschiedene Datentypen verwendbar sind

C++ - Einführung in die Programmiersprache Polymorphismus und Vererbung. Eltern

Software Engineering Klassendiagramme weiterführende Konzepte

1. Grundlegende Eigenscha5en 2. Redefini+on 3. Polymophie 4. Mehrfachvererbung

Einführung in die Programmierung

Primzahlen und RSA-Verschlüsselung

Folge 18 - Vererbung

Fakultät Angewandte Informatik Lehrprofessur für Informatik

2. Semester, 2. Prüfung, Lösung

Zum Abschluss wird gezeigt, wie aus einem C++ Quell-Programm ein ausführbares Programm erzeugt wird. 1. Installation von NetBeans...

Klausur WS 2006/07 Programmiersprache Java Objektorientierte Programmierung II 15. März 2007

Programmiersprache 2 (C++) Prof. Dr. Stefan Enderle NTA Isny

Programmieren in C. Macros, Funktionen und modulare Programmstruktur. Prof. Dr. Nikolaus Wulff

Klassendiagramm. (class diagram)

BEISPIELKLAUSUR Softwareentwicklung:

Angewandte Mathematik und Programmierung

Drei-Schichten-Architektur. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 16: 3-Schichten-Architektur 1 Fachkonzept - GUI

5 DATEN Variablen. Variablen können beliebige Werte zugewiesen und im Gegensatz zu

Zeichen bei Zahlen entschlüsseln

Programmieren Tutorium

Eine Klasse beschreibt Objekte mit gleichen Attributen und Methoden.

13 OOP MIT DELPHI. Records und Klassen Ein Vergleich

1 topologisches Sortieren

5.2 Neue Projekte erstellen

Funktionen Häufig müssen bestimmte Operationen in einem Programm mehrmals ausgeführt werden. Schlechte Lösung: Gute Lösung:

Objektorientierte Programmiersprachen

Das Typsystem von Scala. L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala

Factory Method (Virtual Constructor)

Step by Step Webserver unter Windows Server von Christian Bartl

Innere Klassen in Java

Leichte-Sprache-Bilder

Javakurs 2013 Objektorientierung

Transkript:

8. Objektorientierung und C++ Inhalt: 8.1 Objektorientierung 8.2 Abstrakte Datentypen 8.3 Ziele der Objektorientierung 8.3 C++ - Erweiterungen 8.4 C++ - Klassen, Objekte und Methoden 8.5 C++ - Vererbung und Polymorphie Peter Sobe 1 8.1 Objektorientierung Objektorientierte Programmierung kann auf verschiedene Weise erfolgen: Prozedurale Sprachen in Verbindung mit abstrakten Datentypen Objektorientierte Sprachen, welche die Ziele der Objektorientierung durch eine spezielle Syntaxerweiterung und Verfahren bei der Übersetzung und Laufzeitunterstützung der Programme unterstützen R. Grossmann / P. Sobe 2

Objektorientierung Mit dem objektorientierten Programmier-Paradigma wird ein besonderes Herangehen bei der Modellierung eines Realitätsausschnittes praktiziert. Man sucht dort Entitäten (Autos, Mitarbeiter, Rechnungen, elektr. Bauelemente, mechanische Elemente,...), die bei Verarbeitungsprozessen eine Rolle spielen. Zu einer bestimmten Zeit wird jeweils eine Menge von Entitäten einer bestimmten Sorte, wie Autos oder Personen vorhanden sein. Vergleich mit imperativen, prozeduralem Programmierparadigma: Bisher wurde bei der Modellierung eines Realitätsausschnittes stets nach Verarbeitungsprozessen gesucht und deren Abfolge und Verflechtung als Algorithmus (Steuerfluss) entwickelt und formal beschrieben. R. Grossmann / P. Sobe 3 Objektorientierung Entitätsbegriff - Datenelemente Entität: ist ein in der Realität existierendes und eindeutig identifizierbares Exemplar (Ding, Lebewesen, Gedankenkonstrukt) als Träger von Eigenschaften (Datenelemente), die durch bestimmte Werte beschrieben sind. Beispiel Auto als Entität: Eigenschaft Typ Wert VW-Golf, Eigenschaft Eigentümer Wert Lehmann, Eigenschaft Hubraum Wert 1943, Eigenschaft Tankinhalt Wert 60... Jedes weitere Auto der betrachteten Menge hat die gleichen Eigenschaften, die aber mit anderen Werten belegt sind. R. Grossmann / P. Sobe 4

Grundlagen Methodenbegriff - Elementfunktion Sind alle relevanten Entitätsmengen im Realitätsausschnitt identifiziert, überlegt man, welche Operationen man auf den jeweiligen Entitätsmengen (Autos, Personen, Matrizen,...) benötigt. So wird man Matrizen sicher addieren und multiplizieren wollen, von Personen vielleicht das Alter bestimmen, oder ob sie in Beziehung zu anderen Entitäten stehen (Eigentümer eines Autos). Methode/Elementfunktion: ist eine wohldefinierte Operation / Funktion, die man auf Elemente einer bestimmten Entitätsmenge anwenden darf. Für jede Entitätsmenge ist eine bestimmte Menge solcher Elementfunktionen definiert und ausschließlich an die Anwendung nur auf Elemente dieser Menge gebunden. R. Grossmann / P. Sobe 5 Objektbegriff Die Zusammenfassung von Datenelementen und der über diesen Elementen definierten Elementfunktionen führt zum Objektbegriff. Objekt: ist eine in der Realität existierende Entität, die auf eine Menge von Elementfunktionen zurückgreifen kann. Objekte agieren, indem sie sich gegenseitig Nachrichten senden können, die durch Elementfunktionen bearbeitet werden. Den Bauplan eines jeden Objektes nennt man Typ oder Klasse. R. Grossmann / P. Sobe 6

8.2 Abstrakte Datentypen Bei der Entwicklung größerer Programme wird eine Modularisierung verlangt. Das bedeutet eine Aufteilung des Programmcodes im mehrere Quelldateien (Dateityp/endung.c oder.cpp). Teile eines Programms (Module) werden aus Daten und Funktionen gebildet: Lokale Daten werden dann nur innerhalb der Programmteile benutzt und sind vor den Zugriff von anderer Stelle verborgen Das Programmteil wird ausschließlich über Funktionen (Schnittstellen) angesprochen. Die Funktionen werden in einer Header Datei (Dateityp.h) für andere Programmteile bekannt gemacht. Das ist bereits eine Variante der Objektorientierung. Peter Sobe 7 Abstrakte Datentypen Ein solches Modul, das lokale Daten besitz und Funktionen zum Zugriff bzw. zur Manipulation der lokalen Daten nach außen bereitstellt wird auch abstrakter Datentyp genannt. Beispiel eines Interfaces single_timer.h : void timer_init(); char start(); // starts a timer, returns 1 when successful, otherwise 0 char stop(); // stops a timer, returns 1 when successful, otherwise 0 char get_elapsed_time(int *n_mikrosecs); // returns 1 when a timer has been started, // 0 when timer has not been started, // 2 when timer has been started and stopped Peter Sobe 8

Abstrakte Datentypen Innerhalb single_timer.c wird nun der Startzeitpunkt und der Stopzeitpunkt als lokale Variablen deklariert. Durch Aufruf von init_timer(), start(), stop() und get_elapsed_time(&microsecs) kann ein anderes Modul, bzw. das Hauptprogramm den abstrakten Datentypen benutzten. Man bildet ein Objekt Timer nach. Problem: Bislang ist nur ein Timer verfügbar. Was macht man wenn man mehrere unabhängige Zeiten messen möchte? Peter Sobe 9 Abstrakte Datentypen Abstrakte Datentypen erlauben oft dem Benutzer, mehrere Exemplare d.h. Objekte eines Typs zu erzeugen und über Funktionen anzusprechen. Beispiel eines Interfaces multi_timer.h: timer_id create_timer(); char start(timer_id id); // starts the timer with the specified id, // returns 1 when successful, otherwise 0 // returns -1, if id does not specify a valid timer char stop(timer_id id); char get_elapsed_time(timer_id id, int *n_mikrosecs); char destroy_timer(timer_id id); Peter Sobe 10

8.3 Ziele der Objektorientierung Es sollen kurz die Hauptziele angegeben werden, durch die die Nutzung objektorientierter Sprachen charakterisiert wird: Datenabstraktion: Definition und Verwendung anwendungsbezogener Datentypen und der auf ihnen möglichen Operationen. Datenkapselung: Vereinbarung von Daten und den Prozeduren, die diese Daten verwalten, in einer Programmeinheit. Zugriffe sind über Zugriffsspezifizierer einschränkbar. In der Regel sind die Datenelemente eines Objektes vollständig gekapselt (private) und für den Nutzer nicht einsehbar. Nur über die Elementfunktionen (public) kann der Nutzer das Objekt manipulieren. R. Grossmann / P. Sobe 11 Ziele der Objektorientierung Trennung von Implementierung und Applikation: Durch die Datenkapselung wird es möglich, dass der Programmierer Freiheiten beim Entwurf der (gekapselten) Datenelemente hat. Er ist nur an die Signatur und die äußere Wirkung der Elementfunktionen gebunden. Der Nutzer des Typs benötigt in seiner Applikation ausschließlich das Interface, das die Elementfunktionen bilden. Damit ist eine Applikation vollkommen unabhängig von konkreten internen Kodierungen. Aus Nutzersicht liegt also ein Abstrakter Datentyp (ADT) vor. Er kann nicht mehr zwischen verschieden implementierten Datentypen unterscheiden, da er nur das äußere (identische) Verhalten sieht. R. Grossmann / P. Sobe 12

Ziele der Objektorientierung Spezialisierung und Generalisierung (Vererbung): Durch das Prinzip der Spezialisierung wird es möglich, aus einem Datentyp einen weiteren Datentyp abzuleiten, der viele Gemeinsamkeiten mit ersterem hat und nur in einigen Details abweicht. Der abgeleitete Datentyp erbt Datenstruktur und vererbbare Elementfunktionen vom Basisdatentyp. Es müssen folglich nur die Abweichungen (Spezialisierung) angegeben werden, was den Kodierungsaufwand und die mögliche Fehlerquote stark senkt. Polymorphismus: Das ist in Klassenhierarchien mit Vererbung die Fähigkeit, dass dieselbe Nachricht (Elementfunktion) gesendet an Objekte unterschiedlicher Typen, unterschiedliche Aktionen auslösen kann. R. Grossmann / P. Sobe 13 Ziele der Objektorientierung Überladen von Operatoren: Durch das Prinzip des Überladens von Operatoren ist es möglich, die in einem Namensraum eines Datentyps bekannten Operatoren (z.b. +,-,*,/,...) in einem anderen Datentyp mit zu benutzen, dort aber mit einer anderen Bedeutung. So könnten z.b. die aus den Datentypen int, float usw. bekannten arithmetischen Operatoren auch in einem Datentyp complex verwendet werden. Durch das Überladen des Operators müssen aber die Rechenregeln für den Operator im neuen Typ bekannt gemacht werden. R. Grossmann / P. Sobe 14

Möglichkeiten der Programmierung mit C++ Die Ziele werden durch die Sprache C++ unterstützt. Was ist jetzt möglich? Beispiel 1: Klassenhierarchie geometrischer Objekte Beispiel 2: Klassen mit Operatoren am Beispiel der Klassen Person und Verein Es entsteht ein anderer Programmierstil. Dieser wird durch Festlegung der Klassen und deren Beziehungen dominiert. Objektorientierter Entwurf statt prozeduraler Entwurf. R. Grossmann / P. Sobe 15 Möglichkeiten der Programmierung mit C++ Bespiel 1: Klassenhierarchie geometrischer Objekte Spezielle Klassen punkt, rechteck, kreis oder dreieck sind durch Vererbung von einer allgemeinen Klasse geofigur abgeleitet. Eine abstrakte Klasse geofigur definiert die Menge gemeinsamer Methoden für alle speziellen Objekte, zum Beispiel void zeichne(hdc &hdc); als einheitliches Interface, um das Objekt in einem Fenster zu zeichnen. Objekte anlegen: figuren[0] = new punkt(100.0, 100.0); figuren[1] = new punkt(200.0, 200.0); figuren[2] = new punkt(300.0, 300.0); figuren[3] = new kreis(punkt(400.0,400.0),10.0); figuren[4] = new rechteck(450.0,250.0,80.0,150.0); figuren[5] = new kreis(punkt(400.0, 120.0), 80.0); figuren[6] = new dreieck(200.0, 100.0, 300.0, 100.0, 250.0, 180.0 ); anz_figuren=7; R. Grossmann / P. Sobe 16

Möglichkeiten der Programmierung mit C++ In der Paint-Funktion einer WIN32-Anwendung: for(int i=0; i<anz_figuren; i++) figuren[i]->zeichne(hdc); // figuren[i] ist ein geofigur* Peter Sobe 17 Möglichkeiten der Programmierung mit C++ Beispiel 2: Klassen mit speziellen Operatoren Person schulze( Robert, Schulze,1956, Kaninchenzucht ); meier( Klaus, Meier,1976, Schachspiel ); gartenfreunde = gartenfreunde+meier ; gartenfreunde = gartenfreunde+schulze; gartenfreunde.aufloesung(); Peter Sobe 18

8.3 C++ Erweiterungen C++ stellte einige Erweiterungen bereit, die auch bei nichtobjektorientierter Programmierung benutzt werden können. streambasierte Ein- und Ausgabe Referenzen Speicherallokation und Freigabe mit new und delete (wird später eingeführt) Peter Sobe 19 Streambasierte Ein- und Ausgabe I/O-Objekte cin, cout und cerr mit Operatoren <<, >> Der folgende Programmausschnitt zeigt die typische Nutzung: #include <iostream.h> void main() { int i; float f=7.5; char c[20]= i+f ist gleich ; cout<< \nprogrammstart ; cout<< \neingabe i= ; cin>>i; cout<<c<<i+f<< \n ; } Bemerkenswert ist das Fehlen von Formatierungen (es wird mit Standards gearbeitet) und die Nutzung von Operatoren >> bzw. << für die Ein- bzw. Ausgabe. Peter Sobe 20

Referenzen (1) Eine Referenz ist ein alternativer Name (Alias) für ein Objekt. Die Hauptanwendungen in C++ sind: die Angabe von Argumenten (Parameterkonzept) und Rückkehrwerten bei Funktionen und beim Überladen von Operatoren in Klassen In C++ ist die Schreibweise X& und bedeutet Referenz auf Typ X. Beispiel:... int i=1; int& r =i; // r ist ein zweiter Name für i Peter Sobe 21 Referenzen(2) Aus C sind die beiden Parametervermittlungsarten: call by value und call by reference bekannt. Call by reference wird dabei über Zeiger realisiert. Das ist auch in C++ so möglich. Eine weitere Form des call by reference ist aber die Verwendung von Referenzen anstelle von Zeigern (vgl. Demo-Programme). Peter Sobe 22

Referenzen für Call-by-Reference Parameter void main() { int n1=2, n2, n3; int& r=n2; n2=n3=0; plus_minus(n1, n2, n3); cout <<"\n1="<<n1<<" n2="<<n2<<" n3="<<n3<<endl; //mit Referenz r das gleiche Resultat n2=n3=0; plus_minus(n1, r, n3); cout <<"\n1="<<n1<<" n2="<<n2<<" n3="<<n3<<endl; } void plus_minus(int a, int& b, int& c) { b=a+1; c=b-1; } Peter Sobe 23 8.4 C++ - Klassen, Objekte und Methoden Klassen sind der Bauplan für Objekte und müssen definiert werden. Eine Klassendefinition ist vergleichbar mit einer Type-Definition. class klassenname { private: public: Später können Objekte aus der Klasse erzeugt werden, vergleichbar mit Variablen, die aus eine Typ erzeugt werden. klassenname objekt1; // statisch Deklaration der Datenelemente Deklaration oder Definition der Elementfunktionen objekt2 = new klassenname;.. delete objekt2; // dynamisch Peter Sobe 24

Deklaration der Datenelemente Allgemein dürfen im Deklarationsteil 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 im Deklarationsteil anderer Klassen verwendet werden. Diese bezeichnet man dann als Elementobjekte. Da eine Klasse einen eigenen Gültigkeitsbereich für Namen bildet, sind Datenelemente lokal bezüglich der Klasse und nur Elementfunktionen können Zugriffe auf diese auslösen. Innerhalb einer Klasse darf niemals eine weitere Klassendeklaration vorgenommen werden. R.Grossmann / P. Sobe 25 Deklaration / Definition / Aufruf von Elementfunktionen Elementfunktionen sind einer Klasse zugeordnet und bilden die Menge der Operationen, die mit den Objekten der Klasse ausführbar sind. Damit der Nutzer Elementfunktionen zur Manipulation der Objekte in seinem Anwendungsprogramm aufrufen kann, müssen diese in aller Regel in einem public-teil verfügbar sein. Elementfunktionen sind syntaktisch gesehen - Funktionen im Sinne von C/C++. Die Deklaration und Definition dieser Elementfunktionen genügt den Regeln für normale Funktionen. Durch die Bindung an die Klasse unterscheidet sich der Aufruf von Elementfunktionen gegenüber normalen Funktionen: normale Funktion f(x) Elementfunktion f(x) der Klasse T f(y); T a; a.f(y); R.Grossmann / P. Sobe 26

Definition von Elementfunktionen Beispiel Klasse vektor (1) Deklaration und Definition der Elementfunktionen: class vektor { private: float x; float y; float z; //Deklaration 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);} R.Grossmann / P. Sobe 27 Definition von Elementfunktionen Beispiel Klasse vektor (2) Gewöhnliche Trennung von Deklaration und Definition: class vektor { private: float x; float y; float z; //Deklaration 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 28

Konstruktor, Destruktor Konstruktor: eine ausgewählte Methode, die wie die Klasse benannt ist. kein Rückgabewert kann Parameter entgegen nehmen, die bei Erzeugung eines Objektes anzugeben sind mehrere Konstruktoren mit unterschiedlicher Parameterliste möglich einer der Konstruktoren wird bei Erzeugung einer Klasse ausgeführt Beispiel: class person { public: person(); person(char *vn, char *n, int gebj, char *h); Person unbekannt;// hier wird der parameterlose Konstruktor aufgerufen person *bk = new person( Helmut, Schmidt,1918, Rauchen und Politik ); R.Grossmann / P. Sobe 29 Konstruktor, Destruktor Destruktor: eine ausgewählte Methode, die wie die Klasse mit vorangestelltem ~ -Zeichen benannt ist. kein Rückgabewert, ohne Parameter nur ein Destruktor möglich Destruktor wird bei Ende der Gültigkeit eines Objekts ausgeführt Beispiel: class person { public: ~person(); Hier wird Objekt tmp freigegeben und der Destruktor aufgerufen. void tausch(person &a, person &b) { person tmp; tmp=a; a=b; b=tmp; } R.Grossmann / P. Sobe 30

Konstruktor, Destruktor Am Beispiel der Klasse Person: #define MAX_MITGLIEDER 100 class person { protected: char name[strlen], vorname[strlen], hobby[strlen]; int gebjahr; public: person() {} person(char *vn, char *n, int gebj, char *h) { gebjahr = gebj; strcpy(vorname, vn); strcpy(name, n); strcpy(hobby, h); } ~person() {} void print() { cout << vorname << " " << name << endl; } R.Grossmann / P. Sobe 31 Speicherallokation und Objekte Operatoren new und delete zur Speicherallokation bzw. -freigabe für Objekte Mit dem Operator new wird Speicher im Heap-Speicher angefordert und der Zeigervariablen zugewiesen: Beispiele: int *iptr = new int; int *kptr = new int(64); int *jptr = new int[30]; // ein Speicherbereich für 30 int Werte // wird angefordert person *p = new person( Fritz, Fuchs,1967, Fahrradfahren ); Keine Initialisierung für Standardtypen Bei Objekten wird nach Bereitstellung des Speichers der passende Klassenkonstruktor aufgerufen. Peter Sobe 32

Speicherallokation und Objekte Wird der über new angeforderte Speicherbereich nicht mehr verwendet, so muss er per delete explizit wieder freigegeben werden. int *pint = new int; int *pintfeld = new int[64]; person *pp = new person( Fritz, Fuchs,1967, Fahrradfahren ); delete pint; delete [] pintfeld; delete pp; delete kann nur in Verbindung mit new eingesetzt werden. int i, *pint = new int; int *pint2 = &i; delete pint; delete pint2; // Fehler, da nicht per new erzeugt delete auf einen Null-Pointer hat keine Auswirkungen. Peter Sobe 33 Elementobjekte Der Begriff Elementobjekt wurde zur Bezeichnung von Datenelementen im private-teil einer Klasse eingeführt, die keinen Standardtyp, wie float, int, char usw. repräsentieren, sondern Objekte einer anderen Klasse sind. Beispiel: Sie haben eine Klasse Punkt und wollen jetzt eine Klasse Linie definieren, die von einem Anfangspunkt zu einem Endpunkt geht. Das wäre mit Elementobjekten leicht zu erreichen: Im Programm Punkt_1 steht die Klassendefinition für Punkt: class Punkt { private: float x,y; public: Punkt(float a,float b){ x=a; y=b;} Punkt(){ }... R.Grossmann / P. Sobe 34

Elementobjekte Wir nehmen an, es gäbe die Klasse Punkt, mit einem Konstruktor Punkt(int xpos, int ypos). Nun wird die Klassendefinition für Linie unter Nutzung von Elementobjekten hinzugefügt: class Linie { private: Punkt anfang, ende ; public: Linie(){ }??? Wie muss der Konstruktor Linie geschrieben werden? Es muss ja der Anfangspunkt anfang und der Endpunkt ende mit zulässigen Werten belegt werden!!! Dies kann man nur über die Benutzung sogenannter Elementobjekt-Konstruktoren erreichen! R.Grossmann / P. Sobe 35 Elementobjekte Die Elementobjekt-Konstruktoren benutzen als Namen die Namen der Elementobjekte, in der Klasse Linie also anfang und ende. Der Konstruktor Linie muss deshalb mit Aufruf der Elementobjekt- Konstruktoren geschrieben werden: class Linie { private: Punkt anfang, ende ; public: Linie(float ax,float ay,float bx,float by) : anfang(ax,ay), ende (bx,by) { }... Der Aufruf der Elementobjekt-Konstruktoren muss durch einen Doppelpunkt hinter der Parameter-Liste eingeleitet werden! R.Grossmann / P. Sobe 36

Elementobjekte Besitzt eine Klassendefinition einen Standard-Konstruktor (Konstruktor ohne Parameter), so können im Programm auch Felder mit Elementen dieses Typs deklariert werden. Beispiel vektor class vektor { private: float x,y,z ; public: vektor(){ } // Standardkonstruktor vektor(float ax,float ay,float az) {x=ax;y=ay;z=az; }... In der Applikation (Hauptprogramm) kann jetzt ein Feld fv von vektoren vereinbart werden! vektor fv[4] = { v1, v2, v3, v4 v1-v4 sind vektor-objekte R.Grossmann / P. Sobe 37 Objekte als Parameter (1) C++ erlaubt, Objekte als Parameter von Methoden zu übergeben. Beispiel: Eine Zeichenfläche (canvas), der verschiedene geometrische Objekte übergeben werden. Die Zeichenfläche kann diese Objekte beispielsweise unter Berücksichtigung von 3D- Überdeckungen zeichnen. class geomobj { class canvas { public: public: geomobj() { } canvas() { } int register_geom_obj(geomobj &o) { } void draw_all() { } int num_vertexes(); int get_vertex( int *x, int *y, int *y); int draw_vertex { } R.Grossmann, P.Sobe 38

Objekte als Parameter (2) Bei Übergabe von Objekten an Methoden sind die Mechanismen der Parameterübergabe zu beachten. Bei der Übergabe als Wert würde der Compiler eine lokale Kopie des übergebenen Wertes erzeugen. Dazu wird der Kopierkonstruktor aufgerufen. Dies ist oft nicht wünschenswert (Ressourcenverschwendung, Nebeneffekte). Das bei der Wertübergabe erzeugte Objekt würde wie andere lokale Objekte am Ende der Funktion gelöscht und der zugehörige Destruktor aufgerufen. Das führt i.d.r. zu unerwünschten Wirkungen. Im allgemeinen ist es daher sinnvoll, Objekte als (konstante) Referenz zu übergeben. R.Grossmann, P.Sobe 39 Objekte als Parameter (3) Übergabe von Objekten als Referenz an Methoden: int register_geom_obj(geomobj &o) { for (int i=0; i<o.num_vertexes();i++) o.get_vertex( &geobj[a].v[i].x, &geobj[a].v[i].y, &geobj[a].v[i].z ); } // Kopiert Eckpunktkoordinaten von o auf lokales Objekt geobj[a] besser noch als konstante Referenz: int register_geom_obj(const geomobj &o) { R.Grossmann, P.Sobe 40

8.5 Vererbung und Polymorphie Verschiedene Klassen sind oft in einigen grundlegenden Eigenschaften/Funktionen gleich. Beispielsweise können verschiedene elektr. Bauelemente als Zweipole beschrieben werden. Generalisierung: Ohmscher Widerstand, Diode, Spule usw. sind Zweipole Spezialisierung: Vom Zweipol ausgehend erfolgt eine Spezialisierung als Ohmscher Widerstand durch ein lineares Strom/Spannungs-Verhältnis. als Diode durch eine Sperrfunktion und die Diodenkennlinie als Spule durch einen Induktiven Widerstand und ein phasenabhängiges Strom/Spannungsverhältnis ZP Generalisierung Peter Sobe 41 Generalisierung und Spezialisierung Gemeinsame Eigenschaften und Funktionen können in einer Basisklasse definiert werden. Eine Spezialisierung erfolgt durch Erzeugung einer neuen abgeleiteten Klasse, die die Eigenschaften und Funktion der Basisklasse erbt. Die abgeleitete Klasse kann Neues hinzufügen zusätzliche Elementobjekte und zusätzliche Methoden Die abgeleitete Klasse kann Methoden und Operationen verändern (überschreiben) Objekte der Basisklasse und abgeleiteter Klassen sind zuweisungskompatibel. R.Grossmann, P. Sobe 42

Begriff Klassenhierarchie Definition: Eine Menge von Klassen, deren Elemente durch die Relation Spezialisierung bzw. Generalisierung miteinander in Beziehung gesetzt sind, bezeichnet man als Klassenhierarchie, wenn jede Klasse höchstens eine Basisklasse besitzt. Basisklasse heißt eine Klasse von der durch Spezialisierung eine abgeleitete Klasse gebildet wurde. R.Grossmann, P. Sobe 43 Abgeleitete Klassen in C++Programmen Abgeleitete Klassen müssen in C++ Programmen durch Angabe ihrer Basisklasse gekennzeichnet werden. Beispiel: class A {... class B : public A{... class C: public B{... class D: public A{... //Basis-Klasse //abgeleitete Klasse und gleich- // zeitig Basis-Klasse für C //abgeleitete Klasse //abgeleitete Klasse Alle Datenelemente einer Klasse, sowie alle Methoden mit Ausnahme der unten angegebenen werden an die abgeleitete Klasse vererbt. Nicht vererbt werden alle Konstruktoren und der Destruktor. R.Grossmann, P. Sobe 44

Zugriffsspezifizierer in Klassenhierarchien Alle privaten Datenelemente einer Klasse können nur von den Methoden der Klasse benutzt werden. Sollen diese Datenelemente auch von Methoden der abgeleiteten Klassen erreichbar sein, muss anstelle von private der Spezifizierer protected benutzt werden. Veranschaulichung: class myclass : public yourclass { public: myclass(); ~myclass(); // öffentlich für alle anderen Objekte, // auch für abgeleitete Klassen protected: double calculate(); // nicht öffentlich, kann aber von Klasse // selbst und von abgeleiteter Klasse aufgerufen werden private: void internalaction(); // nur von Klasse selbst aufrufbar, kein Zugriff durch // abgeleitete Klassen R.Grossmann, P. Sobe 45 Konstruktoren abgeleiteter Klassen Konstruktoren werden nicht vererbt. Konstruktoren abgeleiteter Klassen müssen den Konstruktor der Basisklasse aufrufen, der für die Instanziierung der geerbten Anteile sorgt. Beispiel: class A //Basis-Klasse { private: int i; public: A(int k){i=k;} //Konstruktor class B : public A //abgeleitete Klasse { private: char c; public: B(char s,int j): A(j) {c=s;} // : A(j) ruft Basisklassen-Konstruktor auf R.Grossmann, P. Sobe 46

Elementobjektkonstruktoren in Konstruktoren abgeleiteter Klassen Enthalten abgeleitete Klassen Elementobjekte, so müssen neben dem Konstruktor der Basisklasse auch der Elementobjekt- Konstruktor aufgerufen werden. Beispiel: class A { private: int i; public: A(int k){i=k;} //Basis-Klasse //Konstruktor class B : public A //abgeleitete Klasse { private: char c; A a; //Elementobjekt public: B(char s,int j,int m) //Konstruktor abgl. Klasse : a(m),a(j) {c=s;} // A(j) Basisklassen-Konstruktor // a(m) ist Aufruf Elementobjekt-Konstr. R.Grossmann, P. Sobe 47 Elementobjektkonstruktoren in Konstruktoren abgeleiteter Klassen Beachten Sie, dass unabhängig von der Notation die Rufreihenfolge festgelegt ist: 1. Ruf des Konstruktors der Basisklasse 2. Ruf des Elementobjekt-Konstruktors 3. Ruf des Konstruktors der abgeleiteten Klasse Beispiel: class A { //Basis-Klasse class B : public A //abgeleitete Klasse { private: int a, c; public: B(..., int m, int s, ) : a(m),a(j) {c=s;} // zuerst wird A(), dann a() und zuletzt B() ausgeführt R.Grossmann, P.Sobe 48

Vererbung und dynamisches Binden Durch Einfügen der Compilerdirektive virtual wird dynamisches Binden von Methoden erzwungen: class A //Basis-Klasse {public: virtual void Druck(){cout<< Klasse A ;} void Nachricht(){cout<< Nachricht von ; Druck() ;} class B : public A //abgeleitete Klasse { public: void Druck(){cout<< Klasse B ;} void main() {A a; B b; a.nachricht(); b.nachricht(); } Jetzt wird ausgegeben: Nachricht von Klasse A Nachricht von Klasse B R.Grossmann, P. Sobe 49 Beispiel für Polymorphie (1) class B { public: B(int n): b(n) {} virtual void f() {cout << b;} private: int b; class C: public B { public: C(int n1, int n2): B(n1), c(n2) {} virtual void f() {B::f(); cout << c; } private: int c; class D: public C { public: D(int n1, int n2, int n3): C(n1,n2), d(n3) {} virtual void f() {C::f(); cout << d;} private: int d; int main { B* b_array[3]; B b(6); C c(9,12); D d (16,18,20); b_array[0] = &b; b_array[1] = &c; b_array[2] = &d; for(int i=0;i<3;i++) b_array[i]->f(); } R.Grossmann, P. Sobe 50

Beispiel für Polymorphie (2) b_array Ausgabe des Programms: B b(6) 6 9 12 16 18 20 C c(9,12) D d(16,18,20) Es reicht aus, den Typ der Basisklasse zu kennen und einheitliche Methodennamen für Basis- und abgleitete Klassen zu verwenden. Zur Laufzeit werden die Methoden der entsprechenden Objekte (Klassen) richtig ausgewählt, ohne dass sich der Programmierer darum kümmern muss. R.Grossmann, P. Sobe 51 Grafische Veranschaulichung von Klassen (1) Klassen können untereinander verschiedene Beziehungen eingehen: Klasse B als Elementobjekt von Klasse A allgemein kann eine Klasse viele verschiedene Elementobjekte besitzen, die möglicherweise auch Instanzen verschiedener Klassen sind. Elementobjekte können ebenfalls aus verschiedenen Elementobjekten bestehen. Es ergibt sich eine Hierarchie von Elementen, die die Beziehung enthalten in wiederspiegeln. Klasse B als abgeleitete Klasse von A eine Klasse wird typischerweise von einer Basisklasse abgeleitet. Die Basisklasse kann wiederum eine abgeleitete Klasse sein. Es ergibt sich eine Schichtung im Sinne von erbt von. Mehrfachvererbung ist aber auch möglich, d.h. eine Klasse kann von mehreren Basisklassen erben. Klassen können sich über Referenzen assoziieren, d.h. Beziehungen aufbauen, die nicht durch die Elementobjekt-Beziehung abgedeckt ist. Diese Assoziation ist beim Entwurf zu berücksichtigen. Die grafische Darstellung der Hierarchien und Schichtung erfolgt durch Klassendiagramme, die als Teil der UML (Unified Modelling Language) vereinheitlicht wurden. R.Grossmann, P.Sobe 52

Grafische Veranschaulichung von Klassen (2) Objektorientierter Entwurf als Schritt, der vor der eigentlichen Programmierung erfolgt UML Einzelne Klasse: Vererbung: Name der Klasse Zweipol Elementobjekte Methoden BerechneU() spezialisiert OhmscherWiderst Diode BerechneU() BerechneU() R.Grossmann, P.Sobe 53 Grafische Veranschaulichung von Klassen (3) UML Komposition (Ganzes enthält Teile) ElektrSchaltung 1 1..* Zweipol Simuliere() BerechneU() Die Komposition durch Pfeil mit ausgefüllter Raute, wobei Teile nicht ohne das Ganze existieren können. In C++ wird die Komposition z.b. durch Elementobjekte realisiert. Am Pfeil sind Multiplizitäten vermerkt Die Aggregation ist ähnlich, wobei Teile auch ohne das Ganze existieren dürfen. Fahrgemeinschaft 0..1 2..* Fahrgast Reise() Reise () R.Grossmann, P.Sobe 54

Grafische Veranschaulichung von Klassen (4) UML Assoziation eine inhaltliche Beziehung Konto 0.. * 1..* Kunde BucheAb() Kaufe() Klassen können Verweise (Zeiger, Referenzen) auf Objekte verwalten, um inhaltliche Beziehungen zu verwalten. R.Grossmann, P.Sobe 55 Vorgefertigte Klassenbibliotheken Beispiele: Klassenbibliotheken für grafische Ausgabe und Window-Systeme Microsoft MFC, Qt (Unix/Linux-Welt) Klassenbibliotheken für Datenstrukturen (Felder, Arrays, Listen), z.b. Standard Template Library.NET Klassenbibliothek, nutzbar für Programme in C#, C++, Visual Basic Klassenbibliotheken zur Simulation, z.b. SystemC R.Grossmann, P. Sobe 56