19. Vererbung und Polymorphie

Ähnliche Dokumente
7. Vererbung und Polymorphie

18. Vererbung und Polymorphie

18. Vererbung und Polymorphie

19. Vererbung und Polymorphie

22. Subtyping, Polymorphie und Vererbung

Wie schreibe ich ein Powerbook

21. Dynamische Datentypen und Speicherverwaltung

Datenkapselung: public / private

Datenkapselung: public / private

Datenkapselung: public / private class rational { r.d = 0 int n; int d; // INV: d!= Klassen rational r; r.n = 1; // error: n is private

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

Verschlüsseln eines Bildes. Visuelle Kryptographie. Verschlüsseln eines Bildes. Verschlüsseln eines Bildes

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

Binäre Suchbäume. Mengen, Funktionalität, Binäre Suchbäume, Heaps, Treaps

17. Klassen. Datenkapselung, Klassen, Memberfunktionen, Konstruktoren

Dynamische Datentypen. Destruktor, Copy-Konstruktor, Zuweisungsoperator, Dynamischer Datentyp, Vektoren

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

Visuelle Kryptographie. Anwendung von Zufallszahlen

Angewandte Mathematik und Programmierung

Datenkapselung: public / private r.d = 0 class rational { int n; int d; // INV: d!= Klassen rational r; r.n = 1; // error: n is private

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

Kapitel 4.2. Dynamische Datenstrukturen. Nächste Woche: 4. und letzte Schnellübung. Übungsaufgaben: 71-74, 2-aus-4, Rest Bonus.

C++ - Objektorientierte Programmierung Polymorphie

15. Rekursion 2. Motivation: Taschenrechner. Naiver Versuch (ohne Klammern) Analyse des Problems (15 7 3) = Eingabe * 3 = Ergebnis 15

C++ Teil 9. Sven Groß. 17. Juni Sven Groß (IGPM, RWTH Aachen) C++ Teil Juni / 17

Rückblick: Benutzerdefinierte Datentypen Definition der Klasse Vektor als Container für 2-dimensionale Vektoren

C++ Teil 10. Sven Groß. 17. Dez IGPM, RWTH Aachen. Sven Groß (IGPM, RWTH Aachen) C++ Teil Dez / 14

Objektorientierte Programmierung mit C++ SS 2007

Mengen. Binäre Suchbäume. Mengen: Anwendungen (II) Mengen: Lösung mit Listen 12/3/12. Mengen, Funktionalität, Binäre Suchbäume, Heaps, Treaps

Grundlagen der Informatik / Algorithmen und Datenstrukturen. Aufgabe 139

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

Dynamische Datentypen

17. Rekursion 2. Bau eines Taschenrechners, Ströme, Formale Grammatiken, Extended Backus Naur Form (EBNF), Parsen von Ausdrücken

Überblick. Überblick. Abstrakte Klassen - rein virtuelle Funktionen Beispiele

Informatik - Übungsstunde

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

Grundlagen Polymorphismus Eigenschaften virtueller Klassen Mehrfachvererbung bei ROOT. Mehrfache Vererbung. Daniel Beneckenstein. 21.

virtual Wertpapier& operator=(const Wertpapier&); // VIRTUELLE ZUWEISUNG protected: static enum {wortfeldlaenge = 20}; char* name_z; double kurs; };

Algorithmen und Datenstrukturen I Bruder-Bäume

Algorithmen und Datenstrukturen Musterlösung 5

Neben der Verwendung von Klassen ist Vererbung ein wichtiges Merkmal objektorientierter

Programmierkurs C/C++

Tutoraufgabe 1 (Implementierung eines ADTs):

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

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

Einführung in die Systemprogrammierung

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

Einführung in die Programmierung mit C++

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

12/18/12 // POST: values of a and b are interchanged void swap (int& a, int& b) { int c = a; a = b; b = c;

Dynamische Datenstrukturen in C++ 150

Software Entwicklung 1

Software Entwicklung 1

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

Vererbung und Polymorphie

Software Entwicklung 1. Fallstudie: Arithmetische Ausdrücke. Rekursive Klassen. Überblick. Annette Bieniusa / Arnd Poetzsch-Heffter

Prüfung Informatik D-MATH/D-PHYS :00 11:00

7. Übung Informatik II - Objektorientierte Programmierung

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

Name: Klausur Informatik III WS 2003/04

Programmierung und Modellierung

Vorkurs Informatik WiSe 16/17

Programmieren in C++ Überladen von Methoden und Operatoren

Einführung in die Programmierung (EPR)

Programmierkurs C/C++

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

Algorithmen und Datenstrukturen. Bäume. M. Herpers, Y. Jung, P. Klingebiel

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

"Roman Jachs" PR Überblick C++ Roman Jachs 5 AHD 1998/99. Überblick C++

Übung 4: Die generische Klasse AvlBaum in Java 1

Physikalisch Technische Lehranstalt Wedel 31. Januar 2004 Prof. Dr. Uwe Schmidt

15. Rekursion. Rekursive Funktionen, Korrektheit, Terminierung, Aufrufstapel, Bau eines Taschenrechners, BNF, Parsen

Vorkurs Informatik: Erste Schritte der Programmierung mit C++

11 Vererbung und Klassenhierarchie

Algorithmen und Datenstrukturen (Informatik II)

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

Prinzipien der objektorientierten Programmierung (OOP)

Programmierkurs. Steffen Müthing. January 18, Interdisciplinary Center for Scientific Computing, Heidelberg University

Propädeutikum Programmierung in der Bioinformatik

Objektorientiertes Programmieren mit C++ für Fortgeschrittene

Wiederholungsklausur "ADP" WS 2016/2017

4. Objektorientierte Programmierung mit C++

Einführung in die Programmierung mit C++

float: Fließkommazahl nach IEEE 754 Standard mit 32 bit

Vorlesungsprüfung Programmiersprache 1

Klausur im WS 2003/04 : Informatik III

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

Vorkurs Informatik WiSe 17/18

Kapitel 11: Vererbung Ziele von Klassen Einführung in die Informatik für struct Naturwissenschaftler und Ingenieure

12 Abstrakte Klassen, finale Klassen und Interfaces

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

Vererbung und Polymorphie

Fachhochschule Wedel 31. Januar 2004 Prof. Dr. Uwe Schmidt

Name: Klausur Programmierkonzepte WS 2010/11

Transkript:

667 19. Vererbung und Polymorphie Ausdrucksbäume, Vererbung, Code-Wiederverwendung, virtuelle Funktionen, Polymorphie, Konzepte des objektorientierten Programmierens

(Ausdrucks-)Bäume -(3-(4-5))*(3+4*5)/6 / 6 3 + 3 4 5 4 5

(Ausdrucks-)Bäume -(3-(4-5))*(3+4*5)/6 Astgabel / Astgabel 6 Knick 3 4 5 + 3 4 5 Blatt

(Ausdrucks-)Bäume -(3-(4-5))*(3+4*5)/6 Astgabel / Wurzel Astgabel 6 Knick 3 + 3 4 5 4 5 Blatt 668

669 Astgabeln + Blätter + Knicke = Knoten Knoten / 6 Knoten

Astgabeln + Blätter + Knicke = Knoten Knoten / 6 Knoten /

Astgabeln + Blätter + Knicke = Knoten Knoten / 6 Knoten / * = 6

Astgabeln + Blätter + Knicke = Knoten Knoten / 6 Knoten / * = 6

Astgabeln + Blätter + Knicke = Knoten Knoten / 6 Knoten Wert Operator Linker Operand Rechter Operand tree_node / * = 6

669 Astgabeln + Blätter + Knicke = Knoten Knoten / 6 Knoten Wert Operator Linker Operand Rechter Operand tree_node / * = 6 : nicht benutzt

Knoten (struct tree node) tree_node op val left right struct tree_node { char op; // leaf node (op: = ) double val; // internal node ( op: +,,, / ) tree_node left; tree_node right; // constructor tree_node (char o, double v, tree_node l, tree_node r) : op (o), val (v), left (l), right (r) { ; 670

Knoten (struct tree node) tree_node op val left right struct tree_node { char op; // leaf node (op: = ) double val; // internal node ( op: +,,, / ) tree_node left; // == 0 für unäres Minus tree_node right; // constructor tree_node (char o, double v, tree_node l, tree_node r) : op (o), val (v), left (l), right (r) { ; 670

Knoten und Teilbäume 671 / 6 + 3 Knoten = Wurzel eines Teilbaums 3 4 5 4 5

Knoten und Teilbäume 671 / 6 + 3 Knoten = Wurzel eines Teilbaums 3 4 5 4 5 Rechter Teilbaum von

672 Knoten in Teilbäumen zählen struct tree_node { op val left right... // POST: returns the size (number of nodes) of // the subtree with root this int size () const { int s=1; if (left) s += left >size(); if (right) s += right >size(); return s; ;

672 Knoten in Teilbäumen zählen struct tree_node { op val left right... // POST: returns the size (number of nodes) of // the subtree with root this int size () const { int s=1; if (left) // kurz für left!= 0 s += left >size(); if (right) s += right >size(); return s; ;

Teilbäume auswerten struct tree_node { op val left right... // POST: evaluates the subtree with root this double eval () const { if (op == = ) return val; Blatt... double l = 0;... oder Astgabel: if (left) l = left >eval(); op unär, oder linker Ast double r = right >eval(); rechter Ast if (op == + ) return l + r; if (op == ) return l r; if (op == ) return l r; if (op == / ) return l / r; return 0; ; 673

Teilbäume klonen struct tree_node { op val left right... // POST: a copy of the subtree with root this is // made, and a pointer to its root node is // returned tree_node copy () const { tree_node to = new tree_node (op, val, 0, 0); if (left) to >left = left >copy(); if (right) to >right = right >copy(); return to; ; 674

Teilbäume klonen - Kompaktere Schreibweise 675 struct tree_node { op val left right... // POST: a copy of the subtree with root this is // made, and a pointer to its root node is // returned tree_node copy () const { return new tree_node (op, val, ; left? left >copy() : 0, right? right >copy() : 0);

Teilbäume klonen - Kompaktere Schreibweise 675 struct tree_node { op val left right... // POST: a copy of the subtree with root this is // made, and a pointer to its root node is // returned tree_node copy () const { return new tree_node (op, val, ; left? left >copy() : 0, right? right >copy() : 0); cond? expr1 : expr 2 hat Wert expr1, falls cond gilt, expr2 sonst

676 Teilbäume fällen struct tree_node { op val left right... // POST: all nodes in the subtree with root // this are deleted void clear() { if (left) { left >clear(); if (right) { + right >clear(); 3 delete this; ; 3 4 5 4 5

676 Teilbäume fällen struct tree_node { op val left right... // POST: all nodes in the subtree with root // this are deleted void clear() { if (left) { left >clear(); if (right) { + right >clear(); 3 delete this; ; 3 4 5 4 5

676 Teilbäume fällen struct tree_node { op val left right... // POST: all nodes in the subtree with root // this are deleted void clear() { if (left) { left >clear(); if (right) { + right >clear(); 3 delete this; ; 3 4 5 4 5

676 Teilbäume fällen struct tree_node { op val left right... // POST: all nodes in the subtree with root // this are deleted void clear() { if (left) { left >clear(); if (right) { + right >clear(); 3 delete this; ; 3 4 5 4 5

Bäumige Teilbäume 677 struct tree_node {... // constructor tree_node (char o, tree_node l, tree_node r, double v) // functionality double eval () const; void print (std::ostream& o) const; int size () const; tree_node copy () const; void clear (); ;

Bäume pflanzen 678 class texpression { private: tree_node root; public:... texpression (double d) ; erzeugt Baum mit einem Blatt : root (new tree_node ( =, d, 0, 0)) {...

679 Bäume wachsen lassen texpression& operator = (const texpression& e) { assert (e.root); root = new tree_node (, 0, root, e.root >copy()); return this; root e.root *this e

679 Bäume wachsen lassen texpression& operator = (const texpression& e) { assert (e.root); root = new tree_node (, 0, root, e.root >copy()); return this; root e.root *this e

679 Bäume wachsen lassen texpression& operator = (const texpression& e) { assert (e.root); root = new tree_node (, 0, root, e.root >copy()); return this; root e.root *this e

679 Bäume wachsen lassen texpression& operator = (const texpression& e) { assert (e.root); root = new tree_node (, 0, root, e.root >copy()); return this; root e.root->copy() e.root *this e e

679 Bäume wachsen lassen texpression& operator = (const texpression& e) { assert (e.root); root = new tree_node (, 0, root, e.root >copy()); return this; root e.root->copy() e.root e e

679 Bäume wachsen lassen texpression& operator = (const texpression& e) { assert (e.root); root = new tree_node (, 0, root, e.root >copy()); return this; root *this e.root->copy() e.root e e

Bäume züchten 680 texpression operator (const texpression& l, const texpression& r) { texpression result = l; return result = r; texpression a = 3; texpression b = 4; texpression c = 5; texpression d = a b c; 3 4 5

Bäume züchten 680 texpression operator (const texpression& l, const texpression& r) { texpression result = l; return result = r; texpression a = 3; texpression b = 4; texpression c = 5; texpression d = a b c; 3 4 5

Bäume züchten 680 texpression operator (const texpression& l, const texpression& r) { texpression result = l; return result = r; texpression a = 3; texpression b = 4; texpression c = 5; texpression d = a b c; 3 4 5

Bäume züchten 680 texpression operator (const texpression& l, const texpression& r) { texpression result = l; return result = r; texpression a = 3; texpression b = 4; texpression c = 5; texpression d = a b c; 3 4 5

Bäume züchten 680 texpression operator (const texpression& l, const texpression& r) { texpression result = l; return result = r; texpression a = 3; texpression b = 4; texpression c = 5; texpression d = a b c; 3 4 5

Bäume züchten 680 texpression operator (const texpression& l, const texpression& r) { texpression result = l; return result = r; texpression a = 3; texpression b = 4; texpression c = 5; texpression d = a b c; 3 4 5

Werte zu Bäumen! // term = factor { " " factor "/" factor double term (std :: istream& is){ { double value = factor ( is ); while (true) { if (consume (is, )) value = factor ( is ); else if (consume (is, / )) value /= factor ( is ); else return value; calculator.cpp (Ausdruckswert) 682

Werte zu Bäumen! typedef double result_type; // Typ-Alias // term = factor { " " factor "/" factor result_type term (std :: istream& is){ { result_type value = factor ( is ); while (true) { if (consume (is, )) value = factor ( is ); else if (consume (is, / )) value /= factor ( is ); else return value; double_calculator.cpp (Ausdruckswert) 682

Werte zu Bäumen! typedef texpression result_type; // Typ-Alias // term = factor { " " factor "/" factor result_type term (std :: istream& is){ { result_type value = factor ( is ); while (true) { if (consume (is, )) value = factor ( is ); else if (consume (is, / )) value /= factor ( is ); else return value; double_calculator.cpp (Ausdruckswert) texpression_calculator_l.cpp (Ausdrucksbaum) 682

Motivation Vererbung: Bisher 683 Knoten Knoten Knoten 3 4 5 / + 3 4 5 Knoten 6 Astgabeln + Blätter + Knicke = Knoten

Motivation Vererbung: Bisher Knoten / Knoten 6 Knoten 3 + 3 4 5 4 5 Knoten = 5 Astgabeln + Blätter + Knicke = Knoten Unbenutzte Membervariablen 683

Motivation Vererbung: Die Wahrheit 684 Binäre Division Binäre Multiplikation Unäres Minus 3 4 5 / + 3 4 5 Zahl 6 Zoo von Astgabeln, Blättern und Knicken

Motivation Vererbung: Die Idee left right Binäre Division Binäre Multiplikation / 6 Unäres Minus right 3 + 3 4 5 4 5 Zahl val Zoo von Astgabeln, Blättern und Knicken Überall nur die benötigten Membervariablen! 684

Motivation Vererbung: Die Idee left right Binäre Division Binäre Multiplikation Betrag abs + / 6 right 3 3 4 5 4 5 Zahl val Zoo von Astgabeln, Blättern und Knicken Zoo-Erweiterung mit neuen Knoten! 684

Vererbung Der Hack, zum ersten... 685 Szenario: Erweiterung des Ausdrucksbaumes um mathematische Funktionen, z.b. abs, sin, cos:

Vererbung Der Hack, zum ersten... 685 Szenario: Erweiterung des Ausdrucksbaumes um mathematische Funktionen, z.b. abs, sin, cos: Erweiterung der Klasse tree_node um noch mehr Membervariablen struct tree_node{ char op; // neu: op = f > Funktion... std::string name; // function name;

Vererbung Der Hack, zum zweiten... 686 Szenario: Erweiterung des Ausdrucksbaumes um mathematische Funktionen, z.b. abs, sin, cos: Anpassung jeder einzelnen Memberfunktion double eval () const {... else if (op == f ) if (name == "abs") return std::abs(right >eval());...

Vererbung die saubere Lösung 687 xtree node number node unary node binary node Aufspaltung von tree_node minus node abs node

Vererbung die saubere Lösung 687 xtree node number node unary node binary node Aufspaltung von tree_node minus node abs node Gemeinsame Eigenschaften verbleiben in der Basisklasse xtree_node (Erklärung folgt)

Vererbung 688 struct xtree_node{ virtual int size() const; virtual double eval () const; ;

Vererbung 688 struct xtree_node{ virtual int size() const; virtual double eval () const; ; struct number_node : public xtree_node { double val; int size () const; double eval () const; ;

Vererbung 688 struct xtree_node{ virtual int size() const; virtual double eval () const; ; erbt von Vererbung sichtbar struct number_node : public xtree_node { double val; nur für number_node int size () const; double eval () const; ; Mitglieder von xtree_node werden überschrieben

Aufgabenteilung: Der Zahlknoten 690 struct number_node: public xtree_node{ double val; number_node (double v) : val (v) { double eval () const { return val; int size () const { return 1; ;

Ein Zahlknoten ist ein Baumknoten... 691 Ein (Zeiger auf ein) abgeleitetes Objekt kann überall dort verwendet werden, wo ein (Zeiger auf ein) Basisobjekt gefordert ist number_node num = new number_node (5);

Ein Zahlknoten ist ein Baumknoten... 691 Ein (Zeiger auf ein) abgeleitetes Objekt kann überall dort verwendet werden, wo ein (Zeiger auf ein) Basisobjekt gefordert ist number_node num = new number_node (5); xtree_node tn = num; // ok, number_node is // just a special xtree_node

Ein Zahlknoten ist ein Baumknoten... 691 Ein (Zeiger auf ein) abgeleitetes Objekt kann überall dort verwendet werden, wo ein (Zeiger auf ein) Basisobjekt gefordert ist number_node num = new number_node (5); xtree_node tn = num; // ok, number_node is // just a special xtree_node xtree_node bn = new add_node (tn, num); // ok

Ein Zahlknoten ist ein Baumknoten... 691 Ein (Zeiger auf ein) abgeleitetes Objekt kann überall dort verwendet werden, wo ein (Zeiger auf ein) Basisobjekt gefordert ist, aber nicht umgekehrt. number_node num = new number_node (5); xtree_node tn = num; // ok, number_node is // just a special xtree_node xtree_node bn = new add_node (tn, num); // ok number_node nn = tn; //error:invalid conversion

Anwendung class xexpression { private : xtree_node root; public: xexpression (double d) : root (new number_node (d)) { xexpression& operator = (const xexpression& t) { assert (t.root); root = new sub_node (root, t.root >copy()); return this ;... 692

Anwendung class xexpression { statischer Typ private : xtree_node root; dynamischer Typ public: xexpression (double d) : root (new number_node (d)) { xexpression& operator = (const xexpression& t) { assert (t.root); root = new sub_node (root, t.root >copy()); return this ;... 692

Polymorphie 693 Virtuelle Mitgliedsfunktion: der dynamische Typ bestimmt bei Zeigern auf abgeleitete Objekte die auszuführenden Memberfunktionen struct xtree_node { virtual double eval();... ; Ohne virtual wird der statische Typ zur Bestimmung der auszuführenden Funktion herangezogen. Wir vertiefen das nicht weiter.

Polymorphie 693 Virtuelle Mitgliedsfunktion: der dynamische Typ bestimmt bei Zeigern auf abgeleitete Objekte die auszuführenden Memberfunktionen struct xtree_node { virtual double eval();... ; Ohne virtual wird der statische Typ zur Bestimmung der auszuführenden Funktion herangezogen. Wir vertiefen das nicht weiter.

Polymorphie 693 Virtuelle Mitgliedsfunktion: der dynamische Typ bestimmt bei Zeigern auf abgeleitete Objekte die auszuführenden Memberfunktionen struct xtree_node { virtual double eval();... ; Ohne virtual wird der statische Typ zur Bestimmung der auszuführenden Funktion herangezogen. Wir vertiefen das nicht weiter.

Polymorphie 693 Virtuelle Mitgliedsfunktion: der dynamische Typ bestimmt bei Zeigern auf abgeleitete Objekte die auszuführenden Memberfunktionen struct xtree_node { virtual double eval();... ; Ohne virtual wird der statische Typ zur Bestimmung der auszuführenden Funktion herangezogen. Wir vertiefen das nicht weiter.

Aufgabenteilung: Binäre Knoten struct binary_node : public xtree_node { xtree_node left; // INV!= 0 xtree_node right; // INV!= 0 binary_node (xtree_node l, xtree_node r) : left (l), right (r) { assert (left); assert (right); int size () const { return 1 + left >size() + right >size(); ; 694

Aufgabenteilung: Binäre Knoten struct binary_node : public xtree_node { xtree_node left; // INV!= 0 xtree_node right; // INV!= 0 binary_node (xtree_node l, xtree_node r) : left (l), right (r) size funktioniert für { alle binären Knoten. assert (left); Abgeleitete Klassen assert (right); (add_node,sub_node... ) erben diese Funktion! int size () const { return 1 + left >size() + right >size(); ; 694

Aufgabenteilung: +, -, *... 695 struct add_node : public binary_node { add_node (xtree_node l, xtree_node r) : binary_node (l, r) { double eval () const { return left >eval() + right >eval(); ;

Aufgabenteilung: +, -, *... 695 struct sub_node : public binary_node { sub_node (xtree_node l, xtree_node r) : binary_node (l, r) { double eval () const { return left >eval() right >eval(); ;

Aufgabenteilung: +, -, *... 695 struct sub_node : public binary_node { sub_node (xtree_node l, xtree_node r) : binary_node (l, r) { double eval () const { return left >eval() right >eval(); ; eval spezifisch für +, -, *, /

Erweiterung um abs Funktion xtree node unary node number node binary node minus node add node sub node mul node div node 696

Erweiterung um abs Funktion xtree node unary node number node binary node abs node minus node add node sub node mul node div node 696

Erweiterung um abs Funktion struct unary_node: public xtree_node { xtree_node right; // INV!= 0 unary_node (xtree_node r); int size () const; ; struct abs_node: public unary_node { abs_node (xtree_node arg) : unary_node (arg) { double eval () const { return std::abs (right >eval()); ; 697

Erweiterung um abs Funktion struct unary_node: public xtree_node { xtree_node right; // INV!= 0 unary_node (xtree_node r); int size () const; ; struct abs_node: public unary_node { abs_node (xtree_node arg) : unary_node (arg) { double eval () const { return std::abs (right >eval()); ; 697

Da ist noch was... Speicherbehandlung 698 struct xtree_node {... // POST: a copy of the subtree with root // this is made, and a pointer to // its root node is returned virtual xtree_node copy () const; // POST: all nodes in the subtree with // root this are deleted virtual void clear () {; ;

699 Da ist noch was... Speicherbehandlung struct unary_node: public xtree_node {... virtual void clear () { right >clear(); delete this; ; struct minus_node: public unary_node {... xtree_node copy () const { return new minus_node (right >copy()); ;

xtree node ist kein dynamischer Datentyp?? 700 Wir haben keine Variablen vom Typ xtree_node mit automatischer Speicherdauer

xtree node ist kein dynamischer Datentyp?? 700 Wir haben keine Variablen vom Typ xtree_node mit automatischer Speicherdauer Copy-Konstruktor, Zuweisungsoperator und Destruktor sind überflüssig

xtree node ist kein dynamischer Datentyp?? Wir haben keine Variablen vom Typ xtree_node mit automatischer Speicherdauer Copy-Konstruktor, Zuweisungsoperator und Destruktor sind überflüssig Speicherverwaltung in der Container-Klasse class xexpression { // Copy Konstruktor xexpression (const xexpression& v); // Zuweisungsoperator xexpression& operator=(const xexpression& v); // Destruktor ~xexpression (); ; 700

xtree node ist kein dynamischer Datentyp?? Wir haben keine Variablen vom Typ xtree_node mit automatischer Speicherdauer Copy-Konstruktor, Zuweisungsoperator und Destruktor sind überflüssig Speicherverwaltung in der Container-Klasse class xexpression { // Copy Konstruktor xtree_node::copy xexpression (const xexpression& v); // Zuweisungsoperator xexpression& operator=(const xexpression& v); // Destruktor ~xexpression (); ; xtree_node::clear 700

Mission: Monolithisch modular 701 struct tree_node { char op; double val; tree_node left; tree_node right;... ; double eval () const { if (op == = ) return val; else { double l = 0; if (left!= 0) l = left >eval(); double r = right >eval(); if (op == + ) return l + r; if (op == ) return l r; if (op == ) return l r; if (op == / ) return l / r; assert (false); // unknown operator return 0; int size () const {... void clear() {... tree_node copy () const {... + struct number_node: public xtree_node { double val;... double eval () const { return val; ; struct minus_node: public unary_node {... double eval () const { return right >eval(); ; struct minus_node : public binary_node {... double eval () const { return left >eval() right >eval(); struct abs_node : public unary_node {... double eval () const { return left >eval() right >eval();

Zusammenfassung der Konzepte 702.. der objektorientierten Programmierung Kapselung Verbergen der Implementierungsdetails von Typen (privater Bereich) Definition einer Schnittstelle zum Zugriff auf Werte und Funktionalität (öffentlicher Bereich) Ermöglicht das Sicherstellen von Invarianten und den Austausch der Implementierung

Zusammenfassung der Konzepte 703.. der objektorientierten Programmierung Vererbung Typen können Eigenschaften von Typen erben. Abgeleitete Typen können neue Eigenschaften besitzen oder vorhandene überschreiben. Macht Code- und Datenwiederverwendung möglich.

Zusammenfassung der Konzepte 704.. der objektorientierten Programmierung Polymorphie Ein Zeiger kann abhängig von seiner Verwendung unterschiedliche zugrundeliegende Typen haben. Die unterschiedlichen Typen können bei gleichem Zugriff auf ihre gemeinsame Schnittstelle verschieden reagieren. Macht nicht invasive Erweiterung von Bibliotheken möglich.