Am 14. September 2017 haben wir eine überarbeitete Fassung unserer Datenschutzrichtlinie veröffentlicht. Wenn Sie video2brain.com weiterhin nutzen, erklären Sie sich mit diesem überarbeiteten Dokument einverstanden. Bitte lesen Sie es deshalb sorgfältig durch.

C++ Grundkurs

Typqualifizierer constexpr

LinkedIn Learning kostenlos und unverbindlich testen!

Jetzt testen Alle Abonnements anzeigen
Der Typqualifizierer constexpr definiert Variablen, Funktionen und Instanzen einer Klasse, welche ausschließlich zur Compile-Zeit evaluiert werden.
06:21

Transkript

In dieser Lektion stelle ich Ihnen konstante Ausdrücke vor. Konstante Ausdrücke sind Ausdrücke, die zur Kompilierzeit evaluiert werden können. Konstante Ausdrücke werden durch das Schlüsselwort constexpr eingeleitet und die gibt es in drei verschiedenen Formen. Sie können Variablen sein. Sie können Funktionen und Sie können eigenen Datentypen sein. Hier sehen Sie eine Variable. Wenn eine Funktion ein konstanter Ausdruck ist, kann sie auch zur Laufzeit verwendet werden, genau dann wenn die Argumente keine konstanten Ausdrücke sind. Konstante Ausdrücke sind implizit const. Natürlich stellen Sie sich jetzt die Frage, zu was braucht man konstante Ausdrücke. Konstante Ausdrücke besitzen zwei Vorteile. Erstens Ergebnisse, die zur Kompilierzeit als Konstanten vorliegen, müssen zur Laufzeit nicht mehr berechnet werden. D. h., wenn Sie eine Funktion aufrufen, die zur Kompilierzeit evaluiert werden kann, liegt zur Laufzeit nur noch das Ergebnis vor. Der zweite Vorteil ist, der Compiler erhält einen tiefen Einblick in den zu evaluierenden Code und kann daher besser optimieren. Jetzt will ich gerne noch ein bisschen auf die drei verschiedenen Typen von konstanten Ausdrücken eingehen. Das sind Variable, Funktionen und benutzerdefinierte Typen. Variablen: das ist eine constexpr Variable. Wie Sie sehen, wird sie durch das Schlüsselwort constexpr ausgezeichnet oder deklariert. Das Gleiche gilt für die Funktion. Für die Funktion gibt es aber noch zwei Einschränkungen. Erstens, sie muss einen Wert zurückliefern. Zweitens, sie darf nur aus einer Rückgabeanweisung bestehen und muss selbst ein konstanter Ausdruck sein. Das Expression hier muss ein konstanter Ausdruck sein. Für benutzerdefinierte Typen gibt es noch stärkere Einschränkungen. Ich habe hier eine Klasse MyDouble und für die müssen zwei Bedingungen erfüllt sein. Erstens, der Konstruktor muss leer sein und selbst ein konstanter Ausdruck sein. D. h., der muss als constexpr deklariert sein. Zweitens, MyDouble kann Methoden besitzen, die selbst konstante Ausdrücke sind. Wenn diese Zusicherungen erfüllt sind, kann MyDouble zur Kompilierzeit instanziiert werden. Das zeige ich Ihnen jetzt in der Anwendung. Hier habe ich zwei Funktionen und Sie sehen, durch das constexpr werden sie zu konstanten Funktionen. Die Funktion square nimmt ein x an und gibt das Quadrat davon zurück. Die Funktion squareToSquare nimmt die Funktion square an und wendet sie sozusagen zweimal an. Das ist möglich, da die Funktion square selbst ein konstanter Ausdruck ist. Daher darf sie im Funktionskörper der konstanten Ausdrucksfunktion squareToSquare verwendet werden. Hier kommt der besondere Datentyp MyDouble. Das ist ein einfacher rapper um den Datentyp double, der aber zwei double enthält, myVal1 und myVal2. Das Entscheidende ist der Konstruktor hier und die Methode hier. Beide sind als constexpr, als konstante Ausdrücke, deklariert. Der Konstruktor hier nimmt zwei double an, initialisiert damit myVal1 und myVal2 und besitzt einen leeren Funktionskörper. Das war die Zusicherung, die er erfüllen muss. Diese Funktion getSum gibt einfach die Summe er beiden Werten zurück und ist natürlich selbst ein konstanter Ausdruck. Jetzt zeige ich Ihnen das Programm in der Anwendung. Einen kleinen Vorgriff muss ich noch machen. static_assert ist eine neue Funktion in C++ und diese Funktion prüft zur Kompilierzeit, ob dieser Ausdruck hier true oder false ergibt. Wenn dieser Ausdruck true ergibt zur Kompilierzeit, ist es ok. Wenn dieser Ausdruck zu false evaluiert wird, wird diese Fehlermeldung hier ausgegeben und das Programm steigt aus zur Kompilierungszeit. Genau dieses Verhalten benötige ich jetzt, weil ich will zeigen, dass diese Ausdrücke hier zur Kompilierzeit bereits evaluiert werden. square(10) ist das Gleiche wie 100. squareToSquare(10) ist das Gleiche wie 10000 und das gebe ich aus und Sie sehen, ich bekomme hier square(10)=100 und squareToSquare(10) =10000 als Ausgabe heraus. D. h., das Programm übersetzt und die Zusicherung ist erfüllt, dass ich diese Werte zur Kompilierzeit evaluieren kann. Noch genauer ausgedrückt, dass ich diese beiden Werte zur Kompilierzeit evaluiert habe. Dann kann ich square(10) einer constexpr zuweisen. Wenn ich hier kein constexpr verwenden würde, würde diese Zuweisung nicht zulässig sein. Ich kann const-Ausdrücke auch verwenden, um Arrays zu initialisieren. Sehen Sie hier, ich initialisiere auf klassische Weise mit der konstanten 100, aber auch mit den Konstanten aus der constexpr hier und nehme Funktionsaufruf. Aber dieser Aufruf ist natürlich ein konstanter Ausdruck. Hier geht es noch ein bisschen weiter. Hier habe ich den konstanten Ausdruck double, den ich mit myStatVal initialisiere. Jetzt kann ich - und das ist das Besondere - eine Instanz vom Typ MyDouble zur Kompilierzeit initialisieren. Das geht daher, da 10.5 natürlich ein konstanter Ausdruck ist. Das ist das Literal 10.5, das Gleitkomma-Literal. Hier, das hier, habe ich als konstanten Ausdruck hier oben deklariert, daher kann ich das instanziieren und hier auch die Methode getSum aufrufen. Sie sehen, hier teste ich wieder, ob das tatsächlich so ausgeführt wurde, wie ich es mir vorgestellt habe, sprich: zur Kompilierzeit, und es übersetzt. Jetzt noch der letzte Punkt. Sie können konstante Ausdrücke auch zur Laufzeit evaluieren lassen, wenn die konstanten Ausdrücke mit Argumenten umgeben müssen, die nicht zur Kompilierzeit evaluierbar sind. Hier double myDynVal, das ist ein Wert, der zur Kompilierzeit nicht zur Verfügung steht. Das ist kein constexpr-Ausdruck und daher initialisiere ich hier Instanz von der Klasse MyDouble dynamisch, also mit 10.5. Das wäre kein konstanter Ausdruck, aber myDynVal ist eben kein konstanter Ausdruck. Trotzdem kann ich hier getSum aufrufen und trotzdem bekomme ich ein Ergebnis. Nur ich mache in diesem Fall keinen static_assert. Das Ergebnis sehen Sie genau hier unten. In dieser Lektion habe ich Ihnen gezeigt, dass konstante Ausdrücke im Wesentlichen zwei große Vorteile besitzen. Der erste Vorteil ist, sie werden zur Kompilierzeit evaluiert und das Ergebnis steht zur Laufzeit zur Verfügung. Der zweite große Vorteil ist, der Compiler erhält tieferen Einblick in den zu evaluierenden Code und kann besseren optimierten Code produzieren. Konstante Ausdrücke gibt es in drei verschiedenen Formen in C++, als Variable, als Funktionen und als benutzerdefinierte Typen, sprich Klassen.

C++ Grundkurs

Steigen Sie in die mächtige Programmiersprache C++ ein und lernen Sie dabei alle wichtigen Funktionen mit Anwendungsbeispielen kennen.

8 Std. 14 min (147 Videos)
Derzeit sind keine Feedbacks vorhanden...
 

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!