Das siebte Buch: Objektorientierung mit C++ Von Prof. Dr. rer. nat. Ernst-Erich Doberkat Universitat Dortmund EI3 B.G.Teubner Stuttgart· Leipzig· Wiesbaden 2000 Prof. Dr. rer. nat. Ernst-Erich Doberkat Geboren 1948 in Breckerfeld/Westfalen. Studium der Mathematik und Philo sophie an der Ruhr-Universitat Bochum, 1973 Diplom in Mathematik. 1976 Promotion zum Dr. rer. nat. im Fach Mathematik an der Universitat Pader born, 1979 venia /egendi fOr das Fach Informatik an der FernUniversitat Hagen. Von 1981 bis 1985 Associate Professor of Mathematics and Com puter Science am Clarkson College of Technology, Potsdam (New York); LehrstOhle an den Universitaten Hildesheim und Essen, seit 1993 Inhaber des Lehrstuhls fOr Software-Technologie an der Universitat Dortmund. Vie 1- faltige Arbeitsgebiete in der Softwaretechnik, daneben BemOhungen um den Technologie-Transfer und um Multimedia in der akademischen Ausbildung. 1. Auflage August 2000 Die Deutsche Bibliothek - CIP-Einheitsaufnahme Ein Titelsatz fOr diese Publikation ist bei Der Deutschen Bibliothek erMltlich. Aile Rechte vorbehalten © B. G. Teubner Stuttgart· Leipzig' Wiesbaden 2000 Der Verlag Teubner ist ein Unternehmen der Fachverlagsgruppe BertelsmannSpringer. Das Werk einschlieBlich aller seiner Teile ist urheberrechtlich geschOtzt. Jede Verwertung auBerhalb der engen Grenzen des Urheberrechtsgesetzes ist ohne Zustimmung des Verlages un zulassig und strafbar. Das gilt besonders fOr Vervielfaltigungen, Ubersetzungen, Mikroverfilmungen und die Einspeicherung und Verarbeitung in elektronischen Systemen. Konzeption und Layout des Einbands: Peter Pfitz, Stuttgart ISBNI-13: 978-3-519-02649-5 e-ISBN-13: 978-3-322-80104-3 001: 10.1007/978-3-322-80104-3 Dieses Such ist Dr. Rudolf Peter gewidmet. Inhaltsverzeichnis o {// Vorvort ix 1 Die Hofzwerge in der Wiener Hotburg 1 1.1 Die Hierarchie der Hofzwerge 2 1.2 Die Analyse 3 1.3 Aufgaben . 6 2 Erste Schritte 9 2.1 Die Vorgehensweise bei der Programmkonstruktion 10 2.2 Zur Ubersetzung von Programmen 11 2.3 Das erste Programm .. 12 2.4 Die include-Anweisung .. 16 2.5 Elementare Datentypen . . 16 2.6 Einfacbe Ein- und Ausgabe 20 2.7 Eine Anmerkung zum Thema Variablen 22 2.8 Anhang: Schliisselwiirter und reservierte Symbole in C++ 23 2.9 Aufgaben .......................... . 24 3 Einige Beispiele 27 3.1 Ein einfacher Text ...... . 27 3.2 Noch ein einfacher Text; Felder 42 3.3 Ausblick. 47 3.4 Aufgaben ........... . 48 4 Funktionen und lokale Variable 51 4.1 Funktionen ..... . 51 4.2 Zuriick zum Problem. 56 4.3 Zeichenketten. 59 4.4 Der ?-Operator 62 4.5 Aufgaben ... 63 5 Vereinbarung von Namen 67 5.1 Definitionen, Deklarationen und externe Variable 68 5.2 Giiltigkeit von Deklarationen und Definitionen 69 5.3 Namensanalyse ... 72 5.4 Statische Variablen . 74 5.5 Aufgaben ..... . 76 v INHALTSVERZEICHNIS 6 Zeiger: Oh! Jetzt wird es lustig 79 6.1 Adressen ....... . 79 6.2 Die Funktion Tausch .. . 82 6.3 Felder und Zeiger .... . 83 6.4 Funktionen als Parameter 86 6.5 Mehrdimensionale Felder. 87 6.6 Aufgaben ........ . 92 7 Zusammengesetzte Strukturen 95 7.1 struct als Konstruktion . 95 7.2 Verkettete Listen 101 7.3 Aufgaben ....... . 109 8 Binare Biiume und Suche 113 8.1 Eine Suchstruktur ... 113 8.2 Binii.re Baume. . . . . . 114 8.3 Definition von binaren Suchbaumen 116 8.4 Aufgaben .............. . 122 9 Einfache Dateibehandlung 125 9.1 Dateien ......... . 125 9.2 Dateien: Lesen und Schreiben 126 9.3 Handhabung: Einzelheiten . 126 9.4 Aufgaben .......... . 128 10 Funktionale Komponenten und Abstrakte Datentypen 131 10.1 Die Neujahrsansprache ..... 132 10.2 Tiefensuche in binii.ren Baumen 136 10.3 Breitensuche ........ .. 141 10.4 Zugriffsspezifikationen . . . . . 148 10.5 Warteschlangen als Abstrakte Datentypen 151 10.6 Zuriick zur Breitensuche 151 10.7 Statische Komponenten 153 10.8 Was haben wir gelernt? 154 10.9 Aufgaben ....... . 155 11 Prioritiitswarteschlangen 159 11.1 Der Abstrakte Datentyp Prioritatswarteschlange 160 11.2 Heaps ................. . 162 11.3 Noch einmal: Einfiigen in einen Heap. 168 11.4 Der Sortieralgorithmus Heapsort 173 11.5 Ein kurzer Riickblick 175 11.6 Aufgaben ............ . 175 vi INHALTSVERZEICHNIS 12 Graphen 179 12.1 Zur Definition von Graphen ............ . 180 12.2 Zur abstrakten Realisierung ungerichteter Graphen 183 12.3 Der Abstrakte Datentyp UndirGraph . 183 12.4 Pausenmusik ...... . 186 12.5 Der Datentyp Knoten .. 186 12.6 Rcalisierung des Graphen 192 12.7 Beispielprogramm 193 12.8 Aufgaben ........ . 195 13 Klassen - Konstruktionen und Beispiele 199 13.1 Die Klasse Punkt ..... 199 13.2 Uberladen von Methoden 202 13.3 Konstruktoren ..... . 204 13.4 Destruktoren ...... . 206 13.5 Regeln fUr die Anwendung von Konstruktoren und Destruktoren 208 13.6 Aufgaben .............................. . 210 14 Einfache Vererbung 213 14.1 Ein einfUhrendes Beispiel zur Vererbung 214 14.2 Vererbung: das neue Zauberwort .. 217 14.3 Neues Problem: Manner und Frauen 221 14.4 Abstrakte Klassen 227 14.5 Aufgaben .............. . 229 15 Virtuelle Methoden und andere Prazisierungen 231 15.1 Obst, Friichte und andere Agrarprodukte 232 15.2 Rein virtuelle Methoden 239 15.3 Aufgaben ................. . 242 16 Zuriick zu den Hofzwergen: die Implementierung 245 16.1 Zum Programmentwurf ...... . 246 16.2 Die Klasse Hofarbeiter als Wurzel ... . 247 16.3 Die nachste Ebene ............ . 249 16.4 Was haben wir denn jetzt daraus gelernt? 252 16.5 Der Zahlmeister der Hofburg ... 252 16.6 Nachtrag: inline-Vereinbarungen ... 258 17 Hashing: die etwas andere Suchtechnik 261 17.1 Suchoperationen oder: Die Idee beim Hashing 262 17.2 Was ist zu tun? ..... 263 17.3 Der Datentyp IntListe ..... . 264 17.4 Hashing .............. . 267 17.5 Realisierung der Klasse HashTafel 268 17.6 Eine erste Verallgemeinerung 271 17.7 Was lernen wir daraus? 273 17.8 Aufgaben .......... . 273 vii INHALTSVERZEICHNIS 18 Schablonen 271 18.1 Einfiihrendes Beispiel: komplexe Zahlen 278 18.2 Zwischeniiberlegung . . . . . . . . 280 18.3 Einfache Listenkonstruktionen. . . 281 18.4 Hashing fiir beliebige Datentypen . 289 18.5 Hashtafeln als Schablonen . . . 290 18.6 Hashing fiir komplexe Zahlen . 292 18.7 Hashing fiir binii.re Suchbii.ume 293 18.8 Und jetzt geht' s los .... 299 18.9 Riickblick: Vorgehensweise . 299 18.lOAufgaben ..... . 301 19 Ausnahmebehandlung 303 19.1 Ein einfiihrendes Beispiel 304 19.2 Eine differenzierende Betrachtung . 308 19.3 Das Kleingedruckte . 312 19.4 Aufgaben ............. . 313 20 } / /Nachwort 317 Literat urverzeichnis 322 Index 324 viii KapitelO { / / Vorwort Der Werkzeugkasten der Methoden zur objektorientierten Softwarekonstruktion hat sich in der taglichen Praxis des Softwareingenieurs als Kollektion recht wirkungsvoller Hilfsmittel erwiesen. Diese Methoden helfen bei der Konstruktion korrekter, zuverlassiger und wieder verwendbarer Software. Sie begleiten die Konstruktion von der Analyse, also den ersten Ideen eines Programms, tiber den Entwurf bis hin zur Implementierung. Die Objektorientierung dient hierbei anfangs als Richtschnur zur angemessenen Beschreibung der Phanomene, die man modellieren und dann in einem Programm angemessen implementieren mochte. Sie wird in vielen Programmiersprachen durch sprachliche Hilfsmittel untersttitzt - als Schlagworte mogen die Begriffe Klasse, Geheimnisprinzip und Vererbung dienen, so dafi ein objektorien tierter Entwurf auch objektorientiert implementiert werden kann. Objektorientierung als Anfang Da sich objektorientierte Methoden bewii.hrt haben, besteht breiter Konsens daruber, dafi die Einfiihrung in die Informatik mit einer objektorientierten Programmiersprache beginnen soli. Das Argument, mit dem Proponenten der Objektorientierung arbeiten, lautet etwa so: Es gelingt, viele Phanomene der natiirlichen Welt mit objektorientierten Hilfsmitteln auf natiirliche Weise zu modellieren, daher sollte eine Einfiihrung in die Informatik fruh mit diesen Methoden vertraut machen. 1m Tandem mit diesem Argument kommt dann auch eine objektorientierte Programmiersprache. Nun mag man diskutieren, ob die Objektorientierung wirklich eine natiirliche Modellierung ist. Sie ist vielen anderen Modellierungsmethoden uberlegen. Warum das so ist, werden Sie in diesem Buch sehen. Der Beifahrer dieser Argumentation, nii.mlich die Programmiersprache, sollte auch objektorientiert sein. Das ist einsichtig, denn man mochte keinen methodischen Bruch zwischen der Modellierung und der Implementierung, also der Realisierung in einem Programm, entstehen lassen. Solche methodischen Bruche fiihren erfahrungsgemiill leicht zu kognitiven Bruchen, so dafi die Vorteile, die man sich muhsam bei der Modellierung erobert hat, bei der Implementierung verloren zu gehen drohen. Gegenwii.rtig werden zwei objektorientierte Programmiersprachen als Sprachen fiir den aka demischen Anfangsunterricht bevorzugt, nii.mlich die Sprachen JAVA und C++. Die Program miersprache JAVA begann im zweiten Drittel der neunziger Jahre des vorigen Jahrhunderts mit ihrem Siegeszug und scheint unbezwingbar zu sein. Ihre vielen Vorteile machen es ihr leicht, ein Anwendungsfeld nach dem anderen zu erobern. Sie kann ihre Abstammung von ix KAPITEL O. {/I VORWORT c++ und, wenn man genauer hinschaut, von BETA nicht leugnen. Die Programmiersprache C++ hingegen basiert auf der kampferprobten Sprache C, der Basis fur das populiire Be triebssystem UNIX (mit seinen modischen LINux-Varianten). C++ ist die objektorientierte Tochter von C, also eine Spracherweiterung durch objektorientierte Konstruktionen. So entstand dieses Buch Der Verfasser durfte ab WS 97/98 die Dortmunder Erstsemester der Elektrotechnik in die Informatik einfiihren. Auf Bitten der FakuItat fiir Elektrotechnik wurde eine zweisemestri ge Veranstaltung Einfuhrung in die InJormatik for Ingenieure IIIJ konzipiert und in einem zweiten Durchlauf vaIidiert. Sie sollte und soIl nach den Vorstellungen der Fakultat Algo rithmen und Datenstrukturen sowie objektorientierte Konzepte zusammen mit der Program miersprache C++ lehren. Die Entscheidung, C++ aIs Sprache vorzuschlagen, beruhte auf der Beobachtung daB viele Programmkomponenten und Bibliotheken in Coder C++ formu liert sind. Die Studenten werden durch die Veranstaltung unmittelbar in die Lage versetzt, diese Komponenten fur ihre eigene Arbeit zu benutzen (und naturlich eigene Programme zu schreiben). Aus diesen Vorlesungen ist das vorliegende Buch entstanden. Es richtet sich an Nebenfachler der Informatik und an solche Leserinnen und Leser, die sich mit der objektorientierten Pro grammierung und mit C++ vertraut machen wollen. Das Buch wurde so konzipiert, daB auch geistes- und sozialwissenschaftlich orientierte Leser den Ausfiihrungen mit Gewinn folgen konnen. Der Verfasser hat dazu bewuBt Beispiele gewahlt, die nicht dem typischen Umkreis des Ingenieurs oder des Informatikers entstammen, sich vielmehr bemuht, die weitgespannten Anwendungsmoglichkeiten der objektorientierten Modellierung und Programmierung exem plarisch zu zeigen. Das schlii.gt sich auch in den Aufgaben nieder. Der Ton dieses Buchs wurde bewuBt nicht-technisch gehalten. Der gelegentlich unausstehliche Jargon, der sich in der Programmierung breitgemacht hat, soIl soweit als moglich vermieden werden. Die Objektorientierung und die Programmiersprache C++ stehen zwar im Vordergrund die ses Buches, wir beginnen jedoch mit einer Einfiihrung in diejenigen Teile von C++, die aus der Sprache C stammen. Wir fangen auch beim Programmieren nicht gleich mit der Objektorientierung an. Der didaktische Ansatz dieses Buches geht vielmehr von der ob jektbasierte Programmierung in C aus. Objektbasiert bedeutet hier, daB mit Instanzen Ab strakter Datentypen gearbeitet wird, also mit Instanzen von K apseln, die Daten und die Prozeduren auf diesen Daten in einer gemeinsamen Hulle einschlieBen. Der Begriff des Ab strakten Datentypen wird sehr friih eingefiihrt, urn dem Leser moglichst friih Gelegenheit zu geben, Datenabstraktionen gemeinsam mit Funktionsabstraktionen zu benutzen. Tech nisch sieht das so aus, daB die Vorstufe von Klassen, niirnlich zusammengesetzte Strukturen, urn funktionale Komponenten erweitert werden. Damit ist eine objektbasierte Grundlage fiir die weiteren Diskussionen gelegt. Sie wird weidlich genutzt. Wir zeigen an Beispielen, daB dieses Konzept sehr tragfii.hig ist, und sich schon zur ReaIisierung recht mii.chtiger Anwen dungen eignet. Erst dann, wenn diese sprachlichen Hilfsmittel eingefiihrt und ausreichend an Beispielen erprobt worden sind, werden objektorientierte Konzepte eingefiihrt. Klassen erscheinen als Auspragung zusammengesetzter Strukturen, Vererbung und die damit verbun denen Moglichkeiten der Polymorphie werden dann ebenfalls eingefiihrt und an Beispielen erprobt. Die Tragfii.higkeit des Konzepts erweist sich dann an einem groBeren Beispiel, das x recht ausfiihrlich diskutiert wird. Das Buch schliefit mit einer Diskussion von Schablonen (die im eigentlichen Sinne ja nieht mehr objektorientiert sind) und einer kurzen Diskussion der Au snahmebehandlung. Und das steht in diesem Buch Eine kurze Darstellung des Inhalts solI folgen. Fast aile Kapitel beginnen mit der Diskussion einer konkreten Problemstellung, die eine Erweiterung der sprachlichen Miiglichkeiten vor schlagt. Die neuen Ausdrucksmiiglichkeiten werden auf ihre Belastbarkeit gepriift, meist aueh erweitert und auf andere Probleme angewendet. Fast jedes Kapitel enthalt Ubungsaufgaben, die in Anspruch und Umfang von leiehten Etuden zur Einiibung der neuen Techniken bis hin zu kleinen Projekten reichen. Insgesamt sind es 120 Aufgaben geworden. Kapitel 1: Hofzwerge Das Buch beginnt mit der Geschiehte der Hofzwerge in der Wiener Hofburg. Diese Hofzwerge .~ genauer: ihre Besoldungsstruktur - werden nach einigen Seiten hin untersucht. Die Eigenschaften der Hofzwergbesoldung werden als Klassifikationshierarchie gefaJ3t. Damit hat der Leser bereits am Anfang ohne jegliche Programmierkenntnisse einen wichtigen Entwurfsschritt getan. Der so aufgespannte Bogen dehnt sich weit. Er findet erst im letzten Viertel des Buchs sein (anderes) Ende, wenn namlich die Klassifikationshierarchie mit allen ihren dynamischen Aspekten implementiert wird. Der Verfasser mochte auf diese Weise zeigen, daB es durchaus moglich ist, objektorientierte Konzepte einzufiihren, ohne tieferge hende Eigenschaften einer Programmiersprache benutzen zu miissen. DaB dies moglieh ist, belegt die Tragfahigkeit des Konzepts der Objektorientierung. Dieser Bogen dient naturlich auch dazu, das Buch zusammenzuhalten: Die Hofzwerge schauen immer mal wieder um die Ecke und tauchen in der einen oder anderen Ubungsaufgabe auf, bringen sich also in Erinne rung, um die interessanten Eigenschaften, die dieses ulkige Volckehen hat, auch wirklich zurn Funkeln zu bringen. Kapitel 2, 3: C, elementar Die Programmiersprache C wird in ihren elementaren Kom ponenten eingefiihrt. Die sprachlichen Konzepte werden an stetig komplexer werdenden Pro blemstellungen eingefiihrt. In diesen beiden einfiihrenden Kapiteln wird die Philosophie der Vorgehensweise deutlich: Konstruktionen werden nicht urn ihrer selbst willen eingefiihrt, viel mehr sollen konkret vorliegende Probleme damit geliist werden. Solehe einfiihrenden Kapitel sind fast immer ziemlich langweilig, aber diese Durststrecke will uberwunden sein. Der Leser so lite dieses Kapitel vielleicht iiberfliegen, urn bei Bedarf spater nachschlagen zu konnen. Kapitel 4: Funktionen Hier werden Funktionen eingefiihrt. Sie werden als wichtige Struk turierungsmiigliehkeit fiir Programme diskutiert, die dariiber hinaus auch die Moglichkeit geben, die Lokalitat von Namen einzufiihren und zu erkunden. Kapitel 5: Separate Ubersetzung Das Thema der Strukturierung von Programmen wird in diesem Kapitel noch einmal aufgenommen. Hier geht es namlich darum, ein umfangreiches Prograrnm so zu zerlegen, daB die einzelnen Teile in getrennten Dateien aufbewahrt werden konnen. Dazu muB man etwas uber Namensraume wissen, und sie stehen darum in diesem Kapitel im Vordergrund. xi