Martin Aupperle Objektorientiert mitTurbo C++ Aus dem Bereich ,------ ---------------------------------~ Computerliteratur Effektiv Starten mit Turbo C++ von Axel Kotulla Parallele Programmierung mit Modula-2 von Ernst A. Heinz Das Modula-2 Umsfeigerbuch von Rames Abdelhamid z Topspeed Modula 2 von A .. von Anton Liebetrau Turbo Pascal Wegweiser von Ekkehard Kaier Grafik und Animation in C von Herbert Weidner und Bernhard Stauß Programmierung des OS/2 Extended Edition Database Manager von Edgar Zeit Vieweg C++ Toolbox Professionelle Library für Turbo C und Borland C++ von Manfred Rebentisch Obiektorientiert mitTurbo C++ Objektorientierte Softwareentwicklung für Profis von Martin Aupperle Turbo Pascal Version 6.0 Eine Einführung in die objektorientierte Programmierung von Martin Aupperle Microsoft QuickPascal Programmierhandbuch von Kris Jamsa I Ein Microsoft Press I Vieweg-Buchl Turbo Pascal von A .. Z von Anton Liebetrau '-----Vieweg ___________________ __... MARTIN AUPPERLE Obiektorientiert mit TURBOC++ Obiektorientierte Softwareentwicklung für Profis Springer Fachmedien Wiesbaden GmbH Die Deutsche Bibliothek-CIP-Einheitsaufnahme Aupperle, Martin: Objektorientiert mit Turbo C++: objektorientierte Softwareentwicklung flir Profis 1 Martin Aupperle. Braunschweig; Wiesbaden: Vieweg, 1992 ISBN 978-3-322-93858-9 ISBN 978-3-322-93857-2 (eBook) DOI 10.1007/978-3-322-93857-2 Das in diesem Buch enthaltene Programm-Material ist mit keiner Verpflichtung oder Garantie irgend einer Art verbunden. Der Autor und der Verlag Ubemehmen infolgedessen keine Verantwortung und werden keine daraus folgende oder sonstige Haftung iibemehmen, die auf irgendeine Art aus der Benutzung dieses Programm-Materials oderTeilen davon entsteht. Alle Rechte vorbehalten © Springer Fachmedien Wiesbaden 1992 Ursprünglich erschienen bei Friedr. Vieweg & Sohn Verlagsgesellschaft mbH, Braunschweig 1 Wiesbaden, 1992 Softcover reprint ofthe hardcover 1st edition 1992 Das Werk einschlieBiich aller seiner Teile ist urheberrechtlich geschiitzt. Jede Verwertung auBerhalb der engen Grenzen des Urheberrechtsgesetzes ist ohne Zustimmung des Verlags unzuliissig und strafbar. Das gilt insbesondere fiir Ver vielfliltigungen, Obersetzungen, Mikroverfilmungen und die Einspeicherung und Verarbeitung in elektronischen Systemen. Umschlaggestaltung: Schrimpf & Partner, Wiesbaden Gedruckt auf săurefreiem Papier V Inhaltsverzeichnis 1 Vorwort ....................•..................................................... I 2 Warum objektorientierte Programmierung? ••••••••••••••••••••••••••• 4 2.1 Probleme in traditionellen Sprachen ........................................ 4 2.1.1 Das Problem der Datentypen ................................................. 4 2.1.2 Das Problem der Wiederverwendbarkeit von Software ................. 9 2.2 Die Bausteine der objektorientierten Programmierung ................ 13 2.2.1 Kapselung ...................................................................... 13 2.2.2 Vererbung ...................................................................... 13 2.2.3 Polymorphismus .............................................................. 14 3 Die C + + Sprache .......................................................... 16 3.1 C++ und C ................................................................... 16 3.1.1 C+ + als Obermenge von C ............................................... 16 3.1.2 Die Vorteile von C bleiben in C+ + erhalten .......................... 16 3.1.3 C + + und objektorientierte Programmierung .......................... 17 3.2 Die Unterschiede in Stichworten .......................................... 17 3.2.1 Klassen ......................................................................... 17 3.2.2 Konstruktoren und Destruktoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.2.3 Neue Operatoren zur dynamischen Speicherverwaltung .............. 19 3.2.4 Typbestimmung zur Laufzeit ............................................... 19 3.2.5 Überladen von Funktionen ................................................. 20 3.2.6 Überladen von Operatoren .................................................. 20 3.2.7 Inline-Funktionen ............................................................. 21 3.2.8 Vorgabewerte für Argumente .............................................. 21 3.2.9 Typprüfungen ................................................................. 22 3.2.10 Referenztypen ................................................................. 22 4 C + + Teil 1 (Klassen) ..................................................... 24 4.1 Definition einer Klasse ...................................................... 24 4.1.1 Datenelemente ................................................................. 25 4.1.2 Funktionen ..................................................................... 26 4.1.3 Zugriffssteuerung ............................................................. 28 4.2 Objekte ......................................................................... 28 4.3 Zugriff auf Klassenmitglieder .............................................. 29 4.4 Zugriffsfunktionen ........................................................... 30 VI Inhaltsverzeichnis 4.5 Freund-Funktionen und Freund-Klassen ................................. 31 4.6 Höhere Datentypen mit Klassen ........................................... 34 4. 7 Der this-Zeiger ............................................................... 36 4.8 Konstruktoren und Destruktoren .......................................... 37 4.8.1 Konstruktoren ................................................................. 37 4.8.2 Objekte als Datenmitglieder einer Klasse ................................ 40 4.8.3 Konstruktoren und Felder .................................................. 43 4.8.4 Destruktoren ................................................................... 44 4.9 Zuweisung von Objekten ................................................... 46 4.10 Die Alias-Problematik ...................................................... 46 4.11 Objekte als Argumente und Rückgabewerte von Funktionen ........ 50 S Fallstudie Stringverarbeitung ............................................ 53 5.1 Aufgabenstellung ............................................................. 53 5.2 Realisierung ................................................................... 54 5.2.1 Dynamischer Speicher ....................................................... 54 5.2.2 Fehlersituationen ............................................................. 54 5.2.3 Initialisierung ................................................................. 55 5.2.4 Notationeil es .................................................................. 55 5.3 Die Klassendefinition ........................................................ 56 5.3.1 Die Konstruktoren ............................................................ 57 5.3.2 Der Destruktor ................................................................ 58 5.3.3 Der Zugriff auf die Daten .................................................. 58 5.3.4 Das Speichern von Daten ................................................... 59 5.4 Ein vollständiges Programm ............................................... 60 5.5 Ein weitere Klasse ........................................................... 65 5.6 Ausblick ........................................................................ 68 6 C + + Teil 2 .................................................................. 70 6.1 Der Referenztyp .............................................................. 70 6.1.1 Einfache Referenzen ......................................................... 71 6.1.2 Referenzen als Parameter ................................................... 72 6.1.3 Referenzen auf Objekte als Funktionsparameter ........................ 74 6.1.4 Referenzen als Klassenmitglieder ......................................... 77 6.1.5 Referenzen als Funktionsrückgaben ...................................... 78 6.2 Typwandlungen ............................................................... 79 6.2.1 Typwandlungen in C und C + + ........................................... 79 6.2.2 Typwandlungen mit Konstruktoren ....................................... 80 6.2.3 Typwandlung durch Operatorfunktionen ................................ 83 6.2.4 Wandlung beliebiger Typen ................................................ 84 Inhaltsverzeichnis VII 6.2.5 Eindeutigkeitsforderung ..................................................... 86 6.2.6 Temporäre Objekte ........................................................... 88 6.3 Der Kopier-Konstruktor ..................................................... 88 6.3.1 Allgemeine Form des Kopier-Konstruktors ............................. 88 6.3.2 Explizite Initialisierung ..................................................... 89 6.3.3 Parameterübergabe an eine Funktion ..................................... 91 6.3.4 Ergebnisrückgabe von einer Funktion .................................... 91 6.4 Statische Mitglieder .......................................................... 95 6.4.1 Statische Datenmitglieder ................................................... 96 6.4.2 Statische Mitgliedsfunktionen ............................................. 100 6.5 Konstante Objekte ........................................................... 101 6.6 Überladen von Funktionen ................................................ 105 6.6.1 Die Signatur einer Funktion ............................................... 105 6.6.2 Gleiche Funktionalität für unterschiedliche Datentypen ............. 105 6.6.3 Überladen von Mitgliedsfunktionen einer Klasse ..................... 108 6.6.4 Eindeutigkeitsforderung .................................................... 110 6.7 Überladen von Operatoren ................................................. 111 6.7.1 Überladen im klassischen C ............................................... 111 6.7.2 Überladen in C+ + ......................................................... 111 6.7.3 Operatorfunktionen als Mitgliedsfunktionen einer Klasse ........... 115 6.7.4 Beschränkungen ............................................................. 117 6.7.5 Überladen von + + und --................................................. 118 6.7.6 Überladen des Subscript-Operators [] ................................... 121 6.7.7 Überladen des Funktionsaufruf-Operators 0 ........................... 124 6.7.8 Überladen des Zeigerzugriff-Operators -> ............................ 124 6.7.9 Überladen der Zuweisungsoperatoren ................................... 129 6.7.10 Überladen der Operatoren zur dynamischen Speicherverwaltung (new und delete) ............................................................. 132 6.8 structs und unions ........................................................... 135 6.9 Die Operatoren.* und->* ............................................... 137 7 Noch einmal Stringverarbeitung ........................................ 141 7.1 Aufgabenstellung ............................................................ 141 7.2 Der Typ bool ................................................................. 141 7.3 Strings und Zahlen .......................................................... 143 7.4 Vergleich von Strings ...................................................... 144 7.5 Suchen von Zeichen und Zeichenketten ................................. 144 7.6 Teilstrings extrahieren ...................................................... 145 7.7 Zuweisung und Kopierkonstruktor ....................................... 145 VIII Inhaltsverzeichnis 7.8 Verkettung .................................................................... 146 7.9 Ausgeben von Strings auf dem Bildschirm ............................. 147 7.10 Einlesen von Strings von der Tastatur .................................. 147 7.11 Der Operator char* ......................................................... 148 7.12 Deklaration und Definition der Klasse StringT ........................ 148 Datei stringt.hpp ............................................................. 149 Datei stringt.hpi ............................................................. 151 Datei stringt.cpp ............................................................. 152 7.13 Besonderheiten der Implementierung .................................... 160 7.13.1 Dynamische Speicherverwaltung ......................................... 161 7.13.2 Kopierkonstruktor und Zuweisungsoperator ........................... 161 7.13.3 Ergebnistyp StringT& von Operatoren und Funktionen ............. 162 7.13.4 Argument vom Typ StringT& in Operatoren und Funktionen ...... 163 7.13.5 Mehrdeutigkeiten bei überladenen Funktionen ........................ 166 7.13.6 Nocheinmal Typwandlung ................................................. 168 7.13.7 Überraschungen bei der Typwandlung .................................. 168 7.13.8 Der Operator char* ......................................................... 169 7.13.9 Verwendung bereits vorhandener Funktional ität ...................... 170 7.13.10 Konstruktoren für numerische Werte .................................... 170 7.13.11 Strings in StringT ........................................................... 172 7.14 Stilfragen ...................................................................... 172 7.15 Beispiele ....................................................................... 173 7.15.1 Einlesen und Ausgeben ..................................................... 173 7.15.2 Test der Substr-Funktion .................................................. 174 7.16 Nocheinmal: Häufigkeiten im Text feststellen ......................... 175 Datei fieldt.hpp .............................................................. 175 Datei fieldt.cpp .............................................................. 177 Datei test4.cpp ............................................................... 180 7.17 Beachtenswerte Details ..................................................... 183 7.17.1 Verwendung von Referenzen zur Schreibvereinfachung ............. 183 7.17.2 Konstruktor für FieldElemT .............................................. 184 7.17.3 Zugriff auf ProcessToken .................................................. 184 7.17.4 Deklaration der Variablen Separators ................................... 185 7.17.5 Operationen mit Feldelementen ........................................... 185 7.17.6 Zwei Quicksort-Routinen und die Bibliotheksfunktion qsort ....... 187 7.18 Bewertung von StringT .................................................... 188 Inhaltsverzeichnis IX 8 Vererbung .................................................................... 189 8.1 Ein Beispiel. .................................................................. 189 8.2 Neue Mitglieder ............................................................. 190 8.3 Redefinierte Mitglieder ..................................................... 191 8.4 Wann sind Ableitungen sinnvoll? ........................................ 193 8.5 Klassenhierarchien .......................................................... 195 8.6 Mehrfachvererbung ......................................................... 195 8.7 Virtuelle Ableitungen ....................................................... 200 8.8 Zugriffsschutz bei Ableitungen ........................................... 202 8.8.1 Öffentliche Ableitungen .................................................... 202 8.8.2 Das Schlüsselwort protected .............................................. 204 8.8.3 Private Ableitungen ......................................................... 206 8.9 Redeklaration von Zugriffsberechtigungen ............................. 208 8.9.1 Die traditionelle Methode .................................................. 208 8.9.2 Die professionelle Methode ............................................... 210 8.10 Friend-Deklarationen ....................................................... 212 8.11 Konstruktoren in Klassenhierarchien .................................... 214 8.12 Aufrufreihenfolge von Konstruktoren ................................... 219 8.13 Besondere Bedeutung des Standardkonstruktors ...................... 223 8.14 Destruktoren in Klassenhierarchien ...................................... 225 8.15 Destruktoren bei Mehrfachvererbung ................................... 228 8.16 Vererben von Operatorfunktionen ....................................... 231 8.16.1 Spezialfall Zuweisungsoperatoren ........................................ 231 8.17 Erweiterte Zuweisungskompatibilität in Klassenhierarchien ........ 234 9 Basisklasse HeapT zur Verwaltung dynamischen Speichers •.••. 236 9.1 Design der Klasse HeapT .................................................. 237 9.2 Vollständigkeit, Orthogonalität und Redundanzfreiheit .............. 237 9.3 Fehlerbehandlung ............................................................ 238 9.4 Konventionen zu NULL ................................................... 239 9.5 Daten der Klasse HeapT ............................... : ................... 239 9.6 Basisfunktionen der Klasse HeapT ....................................... 240 9.6.1 Konstruktoren und Destruktor ............................................ 241 9.6.2 Speichern von Daten: Die Funktion Put ................................ 241 9.6.3 Füllen mit einem bestimmten Wert: Die Funktion Fill .............. 242 9.6.4 Einfügen von Daten: Die Funktion Ins .................................. 242 9.6.5 Zurückkopieren von Daten: Die Funktion Get ........................ 242 9.6.6 Löschen von Daten: Die Funktion Del. ................................. 243 9.6.7 Der Zuweisungsoperator ................................................... 243