Prof. Dr. Markus Gross Informatik I für D-MAVT (FS 2014)

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

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

11. Klassen. Prof. Dr. François E. Cellier Informatik I für D-ITET (HS 2012)

Einführung in die Programmierung mit C++

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

C++ - Objektorientierte Programmierung Konstruktoren und Destruktoren

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

C++ - Objektorientierte Programmierung Konstante und statische Elemente

Crashkurs C++ Wiederholung

Implementieren von Klassen

Informatik I (D-MAVT)

Programmiertechnik. Teil 4. C++ Funktionen: Prototypen Overloading Parameter. C++ Funktionen: Eigenschaften

9. Funktionen Teil II

7. Übung Informatik II - Objektorientierte Programmierung

Programmierung und Angewandte Mathematik

9 Programmieren von Klassen

Dynamische Datenstrukturen in C++ 150

Prof. W. Henrich Seite 1

Vokabeln. 4.1 Benutzer definierte Datentypen. Kapitel 4. Prof. Dr. Gerhard Berendt C++ oop? SS 2002 Arbeitsblatt 4

Klassen. Kapitel Klassendeklaration

HSR Rapperswil 2001 Markus Rigling. Programmieren: Templates Auflage

C++ - Variablen: Gültigkeit - Sichtbarkeit

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

Informatik - Übungsstunde

C++ Klassen weitere Funktionen

Einführung in die Programmierung Wintersemester 2016/17

3. Exkurs in weitere Arten der Programmierung

Vorlesungsprüfung Programmiersprache 1

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

Repetitorium Informatik (Java)

Konstruktor/Destruktor

Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung)

Repetitorium Programmieren I + II

Informatik 1 ( ) D-MAVT F2011. Klassen, Funktionen. Yves Brise Übungsstunde 9

Objektorientierte Programmierung mit C++ SS 2007

Programmieren in C++ Überladen von Methoden und Operatoren

Algorithmen und Datenstrukturen

4. Objektorientierte Programmierung mit C++

C++ - Objektorientierte Programmierung Polymorphie

Aufbau von Klassen. class punkt {...

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

Einführung in die Programmierung

8. Referenzen und Zeiger

Abgeleitete Datentypen

Programmierkurs C++ Konstruktor, Statische Methoden Namespaces

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

Tag 8 Repetitorium Informatik (Java)

Überblick. R.Grossmann / P. Sobe 1

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

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

initializer lists (nicht für Referenzen... unklar warum...)

Vorlesung Objektorientierte Programmierung Klausur

Repetitorium Programmieren I + II

Pods und Objects (Klassen)

C/C++-Programmierung

C++ Teil 5. Sven Groß. 12. Nov IGPM, RWTH Aachen. Sven Groß (IGPM, RWTH Aachen) C++ Teil Nov / 16

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

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

Grundkurs C++ IDE Klassenhierarchien

Einführung in die Programmiersprache C

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

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

Objektorientierte Programmierung II

Kapitel 9: Klassen und höhere Datentypen. Klassen und höhere. Objekte, Felder, Methoden. Küchlin/Weber: Einführung in die Informatik

Einstieg in die Informatik mit Java

Grundkurs C++ IDE Klassenhierarchien

C++ kompakt - Teil 1. Danke an Matthias Biedermann Markus Geimer

C++ Programmierkurs. Wintersemester 04 / 05. Christian Hagemeier. Lehrstuhl Prof. Dr. Schrader Institut für Informatik Universität zu Köln

16. Structs und Klassen I. Rationale Zahlen, Struct-Definition, Operator-Überladung, Datenkapselung, Klassen-Typen

Überblick. 5. Objekt und Klasse, Elementfunktionen

Grundkurs C++ IDE Klassenhierarchien

5. Abgeleitete Datentypen

5. Abgeleitete Datentypen

13. Vererbung. Prof. Dr. François E. Cellier Informatik I für D-ITET (HS 2012)

A practical guide to C++

Java Methoden. Informatik 1 für Nebenfachstudierende Grundmodul. Kai-Steffen Hielscher Folienversion: 1. Februar 2017

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

7.2 Dynamischer Speicher in Objekten/Kopierkonstruktor

Programmierkurs. Steffen Müthing. November 30, Interdisciplinary Center for Scientific Computing, Heidelberg University

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

Inoffizielle Lösung zur Informatik I Prüfung Frühlingssemester 2010 Freitag, 13. August May 23, 2011

17. Klassen. Überladen von Funktionen. Funktionsüberladung. Operator-Überladung (Operator Overloading) operatorop

Allgemeines - Prinzipien

Objektorientierte Programmierung III

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

PVK Informatik I 1.Teil. Grundlagen Variablen Operatoren Fallunterscheidung Schleifen Kurzschreibweise Pointer Array Dynamische Strukturen Funktionen

10.4 Konstante Objekte

Einführung in die Programmiersprache C

Ein paar Kleinigkeiten zum Einstieg

Einführung in die Programmierung Wintersemester 2018/19

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

Einstieg in die Informatik mit Java

17. Klassen. Datenkapselung, Klassen, Memberfunktionen, Konstruktoren

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

3 Dateien 5. 4 Aufgaben 5. 5 Ausblick 6. Wir wenden uns der Implementierung von Datenstrukturen mittels objekt-orientierter Programmierung

SimpleStat mit Methoden

Programmieren in C++

Transkript:

9. Klassen Prof. Dr. Markus Gross Informatik I für D-MAVT (FS 2014) Objektorientierte Programmierung, Klassen Members Objekte Konstruktoren und Destruktoren this-pointer Public und Private Sections Überladen von Operatoren

Objektorientierung Objektorientierung (OO) ist ein konzeptioneller Ansatz zum Klassendesign, welcher unabhängig von der Programmiersprache ist Merkmale von OO sind: Abstraktion (abstraction) Verkapselung (encapsulation) Polymorphismus (polymorphism) Vererbung (inheritance) Wiederverwendbarkeit (reusability) OO-Programmierung ist datenzentriert Repräsentation der Daten steht im Vordergrund Methoden zur Datenbearbeitung In C++ dient die Klasse zur Implementierung der OO (class) 2

Objektorientierung Merkmale eines klassischen C-Structs: Verkapselt Mitgliedsvariablen Zugriff mittels.-operator Legt fest, wieviel Speicher benötigt wird Bestimmt, welche Operationen auf den Daten möglich sind Operationen (Methoden) werden in Form von Funktionen definiert Funktionen haben globalen Gültigkeitsbereich Idee: Verstecke Daten komplett vor dem Benutzer Zugriff über bestimmte Zugriffsfunktionen Diese Funktionen stellen das Interface zur Klasse Funktionen bekommen somit lokalen Charakter 3

Implementation einer Klasse Erfolgt durch Klassendeklaration Beschreibt Mitgliedsdaten (data members) Und Mitgliedsfunktionen (member functions/methods) Diese stellen das public interface der Klasse dar Sowie durch Definition der Methoden Konvention: Klassennamen schreiben wir mit führendem Grossbuchstaben Eselsbrücke : Die Klasse ist zunächst ein Struct mit lokalen Funktionen und verbesserten Zugriffsrechten! 4

Klassendeklaration Eine Klasse besitzt also sowohl Mitgliedsdaten, als auch Mitgliedsfunktionen Allgemeine Deklarationssyntax sieht wie folgt aus class ClassName { private: data member variables public: member function prototypes // Interface } Zur Verwendung von Mitgliedsfunktionen muss zuerst ein entsprechendes Objekt angelegt werden Aufruf erfolgt mit dem Membership Operator objectname.foo(); 5

Beispiel: Stock-Klasse Benötigte Methoden Neue Aktie ins Portfolio einfügen Aktien kaufen und verkaufen Aktienwert anpassen Anzeige und Darstellung wichtiger Information Benötigte Daten Firmenname Anzahl der Aktien Aktienwert Gesamtwert des Portfolios 6

Beispiel_1: Stock-Klasse class Stock { Private Mitgliedsvariablen private: char company[30]; int shares; double share_val; double total_val; void set_tot() { total_val = shares * share_val;} public: void acquire(const char * co, int n, double pr); void buy(int num, double price); void sell(int num, double price); void update(double price); void show(); }; 7 Oeffentliche Benötigte Methoden Neue Aktie ins Portfolio einfügen Aktien kaufen und verkaufen Aktienwert anpassen Anzeige und Darstellung wichtiger Information Benötigte Daten Firmenname Anzahl der Aktien Aktienwert Gesamtwert des Portfolios Mitgliedsfunktionen

Objekte Stock ist somit als neuer Typenname für eine Klasse deklariert Erlaubt die Definition von Objekten dieses Klassentyps Stock sally; Stock solly; Mit der Definition werden sowohl Mitgliedsvariablen angelegt, als auch Zugriffsfunktionen festgelegt Die Zugriffskonstrolle erfolgt durch die Schlüsselwörter private und public Mitglieder der private section Nur für Klassenmitglieder sichtbar Kein Zugriff von aussen möglich Sind verkapselt (data hiding) 8

Objekte Mitglieder der public section Stellen das Klasseninterface in Form von Zugriffsfunktionen dar Diese können auf private Daten der Klasse zugreifen Verstecken die Details der Implementation Sind von aussen zugreifbar Klasse kann damit als Black Box verwendet werden, wobei nur das Interface bekannt gegeben wird Klassenbibliotheken Wiederverwendbarkeit von Code Goldene Regel: Jegliche Daten sollten möglichst in die private Section der Klasse private ist default Zugriffstyp 9

Mitgliedsfunktionen Definition erfolgt in Analogie zur Definition regulärer Funktionen Verwendung des Scope Operators (::) Haben Zugriff auf die private Section der Klasse Somit kann gleicher Name für verschiedene Klassen verwendet werden Beispiel: void Stock::update(double price) update() wird hier als Mitglied der Klasse Stock definiert update() hat also class scope Stock::update() ist der qualifizierte Name (qualified name) der Methode 10

Beispiel_2: Implementation void Stock::acquire(const char * co, int n, double pr) { strncpy(company, co, 29); // truncate co to fit if needed company[29] = '\0'; shares = n; share_val = pr; set_tot(); } void Stock::buy(int num, double price) { shares += num; share_val = price; set_tot(); } Verwendung privater Mitglieder der Klasse void Stock::sell(int num, double price) { if (num > shares) { cerr << "You can't sell more than you have!\n"; exit(1); } shares -= num; share_val = price; set_tot(); } void Stock::update(double price) { share_val = price; set_tot(); } 11

Beispiel_3: Verwendung int main() { Stock stock1; Definition eines Objektes stock1.acquire("nanosmart", 20, 12.50); cout.precision(2); cout.setf(ios_base::fixed); cout.setf(ios_base::showpoint); // #.## format // #.## format // #.## format } stock1.show(); stock1.buy(15, 18.25); stock1.show(); return 0; Methodenaufrufe 12

Scope und Zugriff Deklaration der Klassen wird in einem getrennten File vorgenommen Headerfile stock.h Definition der Methoden erfolgt im Quellfile stock.cpp Zugriff auf Methoden eines Objektes erfolgt durch bekannten membership Operator Stock kate; kate.show(); // Aufruf einer Mitgliedsfunktion Mitgliedsvariablen müssen für jedes Objekt getrennt verwaltet werden Mitgliedsfunktionen werden vom Compiler nur einmal angelegt! 13

Konstruktoren Daten der private Section der Klasse sind von aussen nicht sichtbar Daher können sie nicht direkt initialisiert werden Vergleiche Struct und dessen Initialisierung Man benötigt eine spezielle Funktion zur Initialisierung Sowohl als Funktionsargument, als auch als Rückgabetyp Dies kann durch einen Konstruktor erreicht werden Wird bei Objektdefinition automatisch aufgerufen Der Name eines Konstruktors entspricht dem Klassennamen Man benötigt Prototyp und Funktionsdefinition Argumente dürfen keine Namen von Mitgliedsvarablen tragen 14

Konstruktoren Beispiel: Stock(const char *co, int n = 0, double pr = 0.0); Stock::Stock(const char *co, int n, double pr) {...} Konstruktoren können explizit bei der Objektdefinition aufgerufen werden Stock food = Stock("World", 250, 1.0); Konstruktoren können implizit aufgerufen werden Stock food("world", 250, 1.0); In Verbindung mit Pointern Stock *pstock = new Stock("World", 250, 1.0); Default Konstruktor wird von C++ angelegt, wenn kein Konstruktor implementiert ist Eigener Default Konstruktor möglich Stock(); 15

Destruktoren Wenn Gültigkeitsbereich des definierten Objektes ausläuft, wird ein Destruktor aufgerufen Destruktoren sorgen für ordnungsgemässe Freigabe von verwendetem Speicher (Kontext new) Destruktoren haben keine Argumente Tragen Klassennamen mit vorgestellter Tilde ~Stock(); // Destruktor Compiler generiert ebenfalls einen Default Konstruktor Destruktoren werden automatisch aufgerufen Stock::~Stock(){... // implementation } Beim fortschrittlichen Klassendesign muss genaustens auf Konstruktoren und Destruktoren geachtet werden 16

Header Files Klassendeklarationen werden in eigene Headerfiles geschrieben Präprozessor-Direktiven verhindern die Mehrfacheinbindung eines Headerfiles #ifndef _STOCK1_H #define _STOCK1_H // place include file contents here #endif Beim ersten Durchlauf wird _STOCK1_H generiert Bei weiteren Aufrufen wird Inhalt ignoriert und somit Mehrfachdeklaration vermieden Beispiel unserer Stock-Klasse 17

Beispiel_4: Headerfile // stock1.h #ifndef _STOCK1_H_ #define _STOCK1_H_ class Stock { Direktive private: char company[30]; int shares; double share_val; double total_val; void set_tot() { total_val = shares * share_val; } public: Stock(); // default constructor Stock(const char * co, int n = 0, double pr = 0.0); ~Stock(); // noisey destructor void buy(int num, double price); void sell(int num, double price); void update(double price); void show(); }; #endif Destruktor Konstruktoren 18

Beispiel_5: Verwendung von Stock // usestok1.cpp -- use the Stock class #include <iostream> using namespace std; #include "stock1.h" int main() { // using constructors to create new objects Stock stock1("nanosmart", 12, 20.0); // syntax 1 Stock stock2 = Stock ("Boffo Objects", 2, 2.0); // syntax 2 cout.precision(2); cout.setf(ios::fixed, ios::floatfield); cout.setf(ios::showpoint); stock1.show(); stock2.show(); stock2 = stock1; // #.## format // #.## format // #.## format // object assignment // using a constructor to reset an object stock1 = Stock("Nifty Foods", 10, 50.0); // temp object } cout << "After stock reshuffle:\n"; stock1.show(); stock2.show(); return 0; 19

Bemerkungen Objekte können einander zugewiesen werden stock1 = stock2; Destruktoren werden am Ende von main aufgerufen Last in First out Mit Konstruktoren können Objekte reinitialisiert werden Dabei legt der Compiler ein unsichtbares, temporäres Objekt zu Kopierzwecken an Dieses wird vom Destruktor wieder gelöscht Implementationsabhängig Konstante Objekte benötigen Funktionen, welche das entsprechende Objekt nicht verändern const Stock land = Stock(...); Neue Art von konstanter Funktion (nachgestellt) void stock::show() const 20

Der this-pointer Manche Mitgliedsfunktionen müssen das Objekt, welches sie aufruft, erkennen Dies erfolgt über den sogenannten this-pointer Beispiel: Funktion, welche zwei Stock-Objekte vergleicht und das grössere Objekt zurückgibt Eine solche Funktion benötigt ein Objekt als Argument Objekt wird von der Funktion nicht verändert Wir verwenden einen Call by Reference Funktion gibt eine Referenz auf das grössere Objekt zurück const Stock & topval(const Stock & s) const; // Prototyp, Funktion verändert Objekt nicht! top = stock1.topval(stock2); //oder auch top = stock2.topval(stock1); 21

Der this-pointer Implementation const Stock & Stock::topval(const Stock & s) const } { if (s.total_val > total_val) else return s; return *this; // Pointer auf Objekt Der this-pointer ist also ein Pointer auf das aufrufende Objekt total_val entspricht also this->total_val this kann in diesem Fall nicht geändert werden 22

Arrays von Objekten Arrays von Objekten können beliebig angelegt werden Beispiel: Stock mystuff[4]; // Definition mystuff[2].show(); // Aufruf Initialisierung erfolgt mittels Konstruktoren In diesem Fall muss ein Default-Konstruktor vorhanden sein Member Variablen haben class scope 23

Speicherklassen Gewöhnliche Variablen innerhalb von Funktionen haben Speicherklasse automatic Ihr Gültigkeitsbereich ist auf den aktuellen Block beschränkt (block scope) Werden bei Eintritt in den Block angelegt Erlöschen bei Austritt aus dem Block Werden auf dem Stack verwaltet Soll eine Variable während des gesamten Programmes Gültigkeit besitzen, so gibt es zwei Möglichkeiten Definition ausserhalb von Funktionen (globale Variable) Verwendung der Speicherklasse static (statische Variable) 24

Speicherklassen Statische Variablen werden durch das zusätzliche Keyword static definiert static int s = 5; Werden automatisch initialisiert und behalten ihren Wert bei Beenden der Funktion (Ausnahme main) Können sinnvoll zur Speicherung funktionsunabhängiger Werte verwendet werden 25

Ueberladen von Operatoren Das Ueberladen von Operatoren ist eine Variante des Polymorphismus Es erlaubt, die gleichen Operatoren für verschiedene Aufgaben zu verwenden In C++ sind bereits diverse Operatoren überladen * steht sowohl für einen Pointer als auch für die Multiplikation & steht sowohl für die Adresse als auch für die Referenz Das Ueberladen bedarf einer Neudefinition des entsprechenden Operators Dies erfolgt durch Implementation einer entsprechenden Operator-Funktion Nur für gültige C++Operatoren möglich! 32

Ueberladen von Operatoren Funktionsheader in allgemeiner Form: operatorop(argument_list) Angenommen, ein + Operator ist überladen Bei Anwendung des Operators auf zwei Objekte district = sid + sara; Ruft der Compiler die entsprechende Operator- Funktion auf district = sid.operator+(sara); Damit entspricht der Operator einem Funktionsaufruf Das sid Objekt wird implizit verwendet (this- Pointer), das sara Objekt explizit als Argument Beispiel: Time-Klasse 33

Beispiel_2: Time-Klasse // mytime1.h -- Time class after operator overloading #ifndef MYTIME1_H_ #define MYTIME1_H _ #include <iostream> using namespace std; class Time { private: int hours; int minutes; public: Time(); Time(int h, int m = 0); void AddMin(int m); void AddHr(int h); void Reset(int h = 0, int m = 0); Time operator+(const Time & t) const; void Show() const; }; #endif 34

Beispiel_2: Time-Methoden // mytime1.cpp - Auszug void Time::Reset(int h, int m) { hours = h; minutes = m; } Ueberladen des Operators Time Time::operator+(const Time & t) const { Time sum; sum.minutes = minutes + t.minutes; sum.hours = hours + t.hours + sum.minutes / 60; sum.minutes %= 60; return sum; } void Time::Show() const { cout << hours << " hours, " << minutes << " } minutes"; cout << '\n'; 35

Beispiel_2: Time-main // usetime1.cpp -- use second draft of Time class // compile usetime1.cpp and mytime1.cpp together #include <iostream> #include "mytime1.h" using namespace std; int main() { Time A; Time B(5, 40); Time C(2, 55); cout << "A = "; A.Show(); cout << "B = "; B.Show(); cout << "C = "; C.Show(); Aufrufe der Operator-Funktion } A = B.operator+(C); // function notation cout << "A = B.operator+(C) = "; A.Show(); B = A + C; // operator notation cout << "A + C = "; B.Show(); return 0; 36

Ueberladen von Operatoren Operatoren können also auf zwei Arten aufgerufen werden A = B.operator+(C); Sowie A = B + C; Das linke Objekt ist das aufrufende Objekt Einschränkungen: Zumindest ein Operand muss ein benutzerdefinierter Typ sein Die Syntax des Originaloperators muss eingehalten werden Die Precedence der Operatoren muss eingehalten werden Neue Operator-Symbole sind NICHT möglich 37

Friend-Funktionen Auf die private Section einer Klasse kann nur mittels Methoden dieser Klasse zugegriffen werden Encapsulation! Manchmal ist dies zu restriktiv Beispiel: Ueberladene Multiplikation A = B*2.75; //entspricht A = B.operator*(2.75); Jedoch A = 2.75*B; //? Asymmetrischer Aufruf Der Aufruf ist nichtkommutativ Zur Zahl existiert keine entsprechende Operator-Funktion Man benötigt eine Funktion, welche nicht Mitglied der Klasse ist und trotzdem auf die private Section zugreifen kann 38

Friend-Funktionen Funktionsaufruf wäre also A = operator*(2.75,b); Entsprechender Prototyp dieser Funktion Time operator*(double m, const Time & t); Linker Operand entspricht erstem Argument Problem: Nicht-Mitgliedsfunktion hat keinen Zugriff auf private Daten der Klasse Einführung der friend-funktion, welche Zugriff auf die private Section der Klasse hat VORSICHT: Hier umgehen wir das Konzept der Verkapselung Kritik an C++ 39

Friend-Funktionen Prototyp der Friend-Funktion wird innerhalb der Klasse deklariert friend Time operator*(double m, const Time & t); Implementation erfolgt konventionell ohne Scope- Operator :: Time operator*(double m, const Time & t) { Time result; Result.hours = totalminutes / 60; totalminutes = t.minutes;... } 40