Vorwort | 8 |
Danksagungen | 13 |
Über den Autor | 15 |
Inhalt | 16 |
1 Grundlagen | 26 |
1.1 Unser erstes Programm | 26 |
1.2 Variablen | 28 |
1.2.1 Fundamentale Typen | 29 |
1.2.2 Characters und Strings | 30 |
1.2.3 Variablen deklarieren | 31 |
1.2.4 Konstanten | 31 |
1.2.5 Literale | 32 |
1.2.6 Werterhaltende Initialisierung | 34 |
1.2.7 Gültigkeitsbereiche | 35 |
1.3 Operatoren | 37 |
1.3.1 Arithmetische Operatoren | 38 |
1.3.2 Boolesche Operatoren | 40 |
1.3.3 Bitweise Operatoren | 41 |
1.3.4 Zuweisung | 42 |
1.3.5 Programmablauf | 43 |
1.3.6 Speicherverwaltung | 44 |
1.3.7 Zugriffsoperatoren | 44 |
1.3.8 Typbehandlung | 44 |
1.3.9 Fehlerbehandlung | 45 |
1.3.10 Überladung | 45 |
1.3.11 Operatorprioritäten | 45 |
1.3.12 Vermeiden Sie Seiteneffekte! | 46 |
1.4 Ausdrücke und Anweisungen | 48 |
1.4.1 Ausdrücke | 48 |
1.4.2 Anweisungen | 49 |
1.4.3 Verzweigung | 49 |
1.4.4 Schleifen | 52 |
1.4.5 goto | 55 |
1.5 Funktionen | 56 |
1.5.1 Argumente | 56 |
1.5.2 Rückgabe der Ergebnisse | 58 |
1.5.3 Inlining | 59 |
1.5.4 Überladen | 59 |
1.5.5 Die main-Funktion | 61 |
1.6 Fehlerbehandlung | 62 |
1.6.1 Zusicherungen | 62 |
1.6.2 Ausnahmen | 64 |
1.6.3 Statische Zusicherungen | 68 |
1.7 I/O | 69 |
1.7.1 Standard-Ausgabe | 69 |
1.7.2 Standard-Eingabe | 70 |
1.7.3 Ein-/Ausgabe mit Dateien | 70 |
1.7.4 Generisches Stream-Konzept | 71 |
1.7.5 Formatierung | 72 |
1.7.6 I/O-Fehler behandeln | 73 |
1.7.7 File-System | 76 |
1.8 Arrays, Zeiger und Referenzen | 77 |
1.8.1 Arrays | 77 |
1.8.2 Zeiger | 79 |
1.8.3 Intelligente Zeiger | 82 |
1.8.4 Referenzen | 85 |
1.8.5 Vergleich zwischen Zeigern und Referenzen | 85 |
1.8.6 Nicht auf abgelaufene Daten verweisen! | 86 |
1.8.7 Containers for Arrays | 87 |
1.9 Strukturierung von Software-Projekten | 89 |
1.9.1 Kommentare | 89 |
1.9.2 Präprozessor-Direktiven | 91 |
1.10 Aufgaben | 95 |
1.10.1 Verengung | 95 |
1.10.2 Literale | 95 |
1.10.3 Operatoren | 95 |
1.10.4 Verzweigung | 95 |
1.10.5 Schleifen | 95 |
1.10.6 I/O | 96 |
1.10.7 Arrays und Zeiger | 96 |
1.10.8 Funktionen | 96 |
2 Klassen | 97 |
2.1 Universell programmieren,nicht detailversessen | 97 |
2.2 Member | 99 |
2.2.1 Mitgliedervariablen | 100 |
2.2.2 Zugriffsrechte | 100 |
2.2.3 Zugriffsoperatoren | 103 |
2.2.4 Der static-Deklarator für Klassen | 103 |
2.2.5 Member-Funktionen | 104 |
2.3 Konstruktoren und Zuweisungen | 105 |
2.3.1 Konstruktoren | 105 |
2.3.2 Zuweisungen | 115 |
2.3.3 Initialisierungslisten | 116 |
2.3.4 Einheitliche Initialisierung | 118 |
2.3.5 Move-Semantik | 120 |
2.3.6 Objekte aus Literalen konstruieren | 126 |
2.4 Destruktoren | 128 |
2.4.1 Implementierungsregeln | 129 |
2.4.2 Richtiger Umgang mit Ressourcen | 129 |
2.5 Zusammenfassung der Methodengenerierung | 135 |
2.6 Zugriff auf Mitgliedervariablen | 136 |
2.6.1 Zugriffsfunktionen | 136 |
2.6.2 Index-Operator | 137 |
2.6.3 Konstante Mitgliederfunktionen | 138 |
2.6.4 Referenz-qualifizierte Mitglieder | 140 |
2.7 Design von Operatorüberladung | 141 |
2.7.1 Seien Sie konsistent! | 141 |
2.7.2 Die Priorität respektieren | 142 |
2.7.3 Methoden oder freie Funktionen | 143 |
2.8 Aufgaben | 146 |
2.8.1 Polynomial | 146 |
2.8.2 Rational | 146 |
2.8.3 Move-Zuweisung | 147 |
2.8.4 Initialisierungsliste | 147 |
2.8.5 Ressourcenrettung | 147 |
3 Generische Programmierung | 148 |
3.1 Funktions-Templates | 148 |
3.1.1 Parametertyp-Deduktion | 149 |
3.1.2 Mit Fehlern in Templates klarkommen | 153 |
3.1.3 Gemischte Typen | 154 |
3.1.4 Einheitliche Initialisierung | 155 |
3.1.5 Automatischer Rückgabetyp | 155 |
3.2 Namensräume und Funktionssuche | 156 |
3.2.1 Namensräume | 156 |
3.2.2 Argumentabhängiges Nachschlagen | 159 |
3.2.3 Namensraum-Qualifizierung oder ADL | 163 |
3.3 Klassen-Templates | 165 |
3.3.1 Ein Container-Beispiel | 165 |
3.3.2 Einheitliche Klassen- und Funktionsschnittstellen entwerfen | 167 |
3.4 Typ-Deduktion und -Definition | 173 |
3.4.1 Automatische Variablentypen | 173 |
3.4.2 Typ eines Ausdrucks | 173 |
3.4.3 decltype(auto) | 174 |
3.4.4 Deduzierte Klassen-Template-Parameter | 176 |
3.4.5 Mehrere Typen deduzieren | 177 |
3.4.6 Typen definieren | 178 |
3.5 Etwas Theorie zu Templates: Konzepte | 180 |
3.6 Template-Spezialisierung | 181 |
3.6.1 Spezialisierung einer Klasse für einen Typ | 181 |
3.6.2 Funktionen Spezialisieren und Überladen | 183 |
3.6.3 Partielle Spezialisierung von Klassen | 185 |
3.6.4 Partiell spezialisierte Funktionen | 186 |
3.6.5 Strukturierte Bindung mit Nutzertypen | 188 |
3.7 Nicht-Typ-Parameter für Templates | 191 |
3.7.1 Container fester Größe | 191 |
3.7.2 Nicht-Typ-Parameter deduzieren | 194 |
3.8 Funktoren | 194 |
3.8.1 Funktionsartige Parameter | 196 |
3.8.2 Funktoren zusammensetzen | 197 |
3.8.3 Rekursion | 199 |
3.8.4 Generische Reduktion | 202 |
3.9 Lambdas | 203 |
3.9.1 Objekte erfassen | 204 |
3.9.2 Generische Lambdas | 208 |
3.10 Variablen-Templates | 208 |
3.11 Variadische Templates | 210 |
3.11.1 Rekursive Funktionen | 210 |
3.11.2 Direkte Expansion | 212 |
3.11.3 Indexsequenzen | 213 |
3.11.4 Faltung | 215 |
3.11.5 Typgeneratoren | 216 |
3.11.6 Wachsende Tests | 216 |
3.12 Übungen | 218 |
3.12.1 String-Darstellung | 218 |
3.12.2 String-Darstellung von Tupeln | 218 |
3.12.3 Generischer Stack | 219 |
3.12.4 Rationale Zahlen mit Typparameter | 219 |
3.12.5 Iterator eines Vektors | 219 |
3.12.6 Ungerader Iterator | 219 |
3.12.7 Bereich von ungeraden Zahlen | 220 |
3.12.8 Stack von bool | 220 |
3.12.9 Stack mit nutzerdefinierter Größe | 220 |
3.12.10 Deduktion von Nicht-Typ-Template-Argumenten | 220 |
3.12.11 Trapez-Regel | 221 |
3.12.12 Partielle Spezialisierung mit einer statischen Funktion | 221 |
3.12.13 Funktor | 221 |
3.12.14 Lambda | 221 |
3.12.15 Implementieren Sie make_unique | 222 |
4 Bibliotheken | 223 |
4.1 Standard-Template-Library | 224 |
4.1.1 Einführendes Beispiel | 224 |
4.1.2 Iteratoren | 225 |
4.1.3 Container | 230 |
4.1.4 Algorithmen | 239 |
4.1.5 Jenseits von Iteratoren | 244 |
4.1.6 Parallele Berechnung | 246 |
4.2 Numerik | 247 |
4.2.1 Komplexe Zahlen | 247 |
4.2.2 Zufallszahlengeneratoren | 250 |
4.2.3 Mathematische Spezialfunktionen | 259 |
4.3 Meta-Programmierung | 260 |
4.3.1 Wertgrenzen | 260 |
4.3.2 Typeigenschaften | 262 |
4.4 Utilities | 264 |
4.4.1 optional | 264 |
4.4.2 Tupel | 265 |
4.4.3 variant | 268 |
4.4.4 any | 270 |
4.4.5 string_view | 271 |
4.4.6 function | 272 |
4.4.7 Referenz-Wrapper | 275 |
4.5 Die Zeit ist gekommen | 277 |
4.6 Parallelität | 279 |
4.6.1 Terminologie | 279 |
4.6.2 Überblick | 280 |
4.6.3 Threads | 280 |
4.6.4 Rückmeldung an den Aufrufer | 282 |
4.6.5 Asynchrone Aufrufe | 283 |
4.6.6 Asynchroner Gleichungslöser | 285 |
4.6.7 Variadische Mutex-Sperre | 289 |
4.7 Wissenschaftliche Bibliotheken jenseits des Standards | 291 |
4.7.1 Andere Arithmetiken | 291 |
4.7.2 Intervallarithmetik | 292 |
4.7.3 Lineare Algebra | 292 |
4.7.4 Gewöhnliche Differentialgleichungen | 293 |
4.7.5 Partielle Differentialgleichungen | 293 |
4.7.6 Graphenalgorithmen | 294 |
4.8 Übungen | 294 |
4.8.1 Sortierung nach Betrag | 294 |
4.8.2 Suche mit einem Lambda als Prädikat | 294 |
4.8.3 STL-Container | 295 |
4.8.4 Komplexe Zahlen | 295 |
4.8.5 Parallele Vektoraddition | 296 |
4.8.6 Refaktorisierung der parallelen Addition | 296 |
5 Meta-Programmierung | 298 |
5.1 Lassen Sie den Compiler rechnen | 298 |
5.1.1 Kompilierzeitfunktionen | 298 |
5.1.2 Erweiterte Kompilierzeitfunktionen | 300 |
5.1.3 Primzahlen | 302 |
5.1.4 Wie konstant sind unsere Konstanten? | 304 |
5.1.5 Kompilierzeit-Lambdas | 305 |
5.2 Typinformationen | 306 |
5.2.1 Typabhängige Funktionsergebnisse | 306 |
5.2.2 Bedingte Ausnahmebehandlung | 310 |
5.2.3 Ein Beispiel für eine const-korrekte View | 311 |
5.2.4 Standard-Typmerkmale | 318 |
5.2.5 Domän-spezifische Type-Traits | 318 |
5.2.6 Typeigenschaften mit Überladung | 320 |
5.2.7 enable_if | 322 |
5.2.8 Variadische Templates überarbeitet | 326 |
5.3 Expression-Templates | 329 |
5.3.1 Einfache Implementierung eines Additionsoperators | 329 |
5.3.2 Eine Klasse für Expression-Templates | 333 |
5.3.3 Generische Expression-Templates | 335 |
5.4 Compiler-Optimierung mit Meta-Tuning | 337 |
5.4.1 Klassisches Abrollen mit fester Größe | 338 |
5.4.2 Geschachteltes Abrollen | 342 |
5.4.3 Aufwärmung zum dynamischen Abrollen | 348 |
5.4.4 Abrollen von Vektorausdrücken | 349 |
5.4.5 Tuning von Expression-Templates | 351 |
5.4.6 Tuning von Reduktionen | 354 |
5.4.7 Tuning geschachtelter Schleifen | 361 |
5.4.8 Resümee des Tunings | 366 |
5.5 Turing-Vollständigkeit | 368 |
5.6 Übungen | 371 |
5.6.1 Type-Traits | 371 |
5.6.2 Fibonacci-Sequenz | 371 |
5.6.3 Meta-Programm für den größten gemeinsamen Divisor | 371 |
5.6.4 Rationale Zahlen mit gemischten Typen | 372 |
5.6.5 Vektor-Expression-Template | 372 |
5.6.6 Meta-Liste | 373 |
6 Objektorientierte Programmierung | 374 |
6.1 Grundprinzipien | 374 |
6.1.1 Basis- und abgeleitete Klassen | 375 |
6.1.2 Konstruktoren erben | 378 |
6.1.3 Virtuelle Funktionen | 379 |
6.1.4 Funktoren über Vererbung | 386 |
6.1.5 Abgeleitete Klassen für Ausnahmen | 387 |
6.2 Redundanz entfernen | 388 |
6.3 Mehrfachvererbung | 390 |
6.3.1 Mehrere Eltern | 390 |
6.3.2 Gemeinsame Großeltern | 391 |
6.4 Dynamische Auswahl von Subtypen | 396 |
6.5 Konvertierung | 398 |
6.5.1 Umwandlungen zwischen abgeleiteten Klassen | 399 |
6.5.2 const_cast | 403 |
6.5.3 Umdeutung | 404 |
6.5.4 Umwandlung im Funktionsstil | 404 |
6.5.5 Implizite Umwandlungen | 406 |
6.6 CRTP | 407 |
6.6.1 Ein einfaches Beispiel | 407 |
6.6.2 Ein wiederverwendbarer Indexoperator | 409 |
6.7 Übungen | 411 |
6.7.1 Nicht-redundante Raute | 411 |
6.7.2 Vektorklasse mit Vererbung | 411 |
6.7.3 Ausnahmen in Vektor refaktorisieren | 411 |
6.7.4 Test auf geworfene Ausnahme | 412 |
6.7.5 Klonfunktion | 412 |
7 Wissenschaftliche Projekte | 413 |
7.1 Implementierung von ODE-Lösern | 413 |
7.1.1 Gewöhnliche Differentialgleichungen | 413 |
7.1.2 Runge-Kutta-Algorithmen | 416 |
7.1.3 Generische Implementierung | 417 |
7.1.4 Ausblick | 424 |
7.2 Projekte erstellen | 424 |
7.2.1 Build-Prozess | 425 |
7.2.2 Build-Tools | 429 |
7.2.3 Separates Kompilieren | 433 |
7.3 Einige abschließende Worte | 439 |
A Weitschweifendes | 441 |
A.1 Mehr über gute und schlechte Software | 441 |
A.2 Grundlagen im Detail | 447 |
A.2.1 Statische Variablen | 447 |
A.2.2 Mehr über if | 447 |
A.2.3 Duff’s Device | 449 |
A.2.4 Programmaufrufe | 449 |
A.2.5 Zusicherung oder Ausnahme? | 450 |
A.2.6 Binäre I/O | 451 |
A.2.7 I/O im Stile von C | 452 |
A.2.8 Garbarge-Collection | 453 |
A.2.9 Ärger mit Makros | 454 |
A.3 Praxisbeispiel: Matrix-Invertierung | 455 |
A.4 Klassendetails | 465 |
A.4.1 Zeiger auf Mitglieder | 465 |
A.4.2 Weitere Initialisierungsbeispiele | 465 |
A.4.3 Zugriff auf mehrdimensionale Datenstrukturen | 466 |
A.5 Methodengenerierung | 469 |
A.5.1 Automatische Generierung | 470 |
A.5.2 Steuerung der Generierung | 472 |
A.5.3 Generierungsregeln | 473 |
A.5.4 Fallstricke und Designrichtlinien | 477 |
A.6 Template-Details | 481 |
A.6.1 Einheitliche Initialisierung | 481 |
A.6.2 Welche Funktion wird aufgerufen? | 481 |
A.6.3 Spezialisierung auf spezifische Hardware | 484 |
A.6.4 Variadisches binäres I/O | 485 |
A.7 Mehr über Bibliotheken | 486 |
A.7.1 std::vector in C++03 verwenden | 486 |
A.7.2 variant mal nerdisch | 487 |
A.8 Dynamische Auswahl im alten Stil | 487 |
A.9 Mehr über Meta-Programmierung | 488 |
A.9.1 Das erste Meta-Programm in der Geschichte | 488 |
A.9.2 Meta-Funktionen | 490 |
A.9.3 Rückwärtskompatible statische Zusicherung | 491 |
A.9.4 Anonyme Typparameter | 492 |
A.9.5 Benchmark-Quellen für dynamisches Abrollen | 496 |
A.9.6 Benchmark für Matrixprodukt | 497 |
B Werkzeuge | 498 |
B.1 g++ | 498 |
B.2 Debugging | 499 |
B.2.1 Textbasierte Debugger | 499 |
B.2.2 Debugging mit graphischen Interface: DDD | 501 |
B.3 Speicheranalyse | 503 |
B.4 gnuplot | 504 |
B.5 Unix, Linux und Mac OS | 505 |
C Sprachdefinitionen | 507 |
C.1 Wertkategorien | 507 |
C.2 Konvertierungsregeln | 510 |
C.2.1 Aufwertung | 511 |
C.2.2 Andere Konvertierungen | 511 |
C.2.3 Arithmetische Konvertierungen | 512 |
C.2.4 Verengung | 513 |
Literatur | 514 |
Abbildungsverzeichnis | 517 |
Tabellenverzeichnis | 518 |
Index | 519 |