Peter Gottschling
Forschung mit modernem C++
C++17-Intensivkurs für Wissenschaftler, Ingenieure und Programmierer
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
© 2009-2024 ciando GmbH