const_cast
kann die Konsistenz eines Objekts nicht löschen. const_cast
kann nur die Konstanz von einem Zugriffspfad zu einem Objekt entfernen. Zugriffspfad ist ein Zeiger oder eine Referenz auf ein Objekt. Das Entfernen der Konstante aus dem Zugriffspfad hat absolut keine Auswirkung auf das Objekt selbst. Selbst wenn Sie const_cast
verwenden, um die Konsistenz des Zugriffspfads zu entfernen, erhalten Sie damit nicht unbedingt die Berechtigung, das Objekt zu ändern. Ob Sie es tun können oder nicht, hängt vom Objekt selbst ab. Wenn es const ist, dürfen Sie es nicht ändern und alle Versuche führen zu undefiniertem Verhalten.
Dies veranschaulicht beispielsweise die beabsichtigte Verwendung von const_cast
Der einzige Grund, warum das Obige legal und gültig ist, ist die Tatsache, dass i
eigentlich ein nicht-konstantes Objekt ist, und wir wissen davon.
Wenn das ursprüngliche Objekt wirklich konstant war, würde der obige Code undefiniertes Verhalten erzeugen:
%Vor% C ++ Sprache erlaubt es Ihnen nicht, konstante Objekte zu ändern und const_cast
ist hier völlig machtlos, egal wie Sie es benutzen.
mutable
ist eine ganz andere Sache. mutable
erstellt ein Datenfeld, das rechtlich geändert werden kann, auch wenn das enthaltende Objekt const
deklariert ist. In diesem Sinne erlaubt es mutable
, [bestimmte Teile von] konstanten Objekten zu modifizieren. const_cast
dagegen kann nichts dergleichen tun.
Der Unterschied ist, dass const_cast
nicht schummeln kann, aber mutable
ist eine Ausnahme von den Regeln.
Beim ersten Snippet m_a
ist mutable
und damit eine Ausnahme von der Regel, dass Sie Datenelemente in const
-Memberfunktionen nicht ändern können.
Im zweiten Ausschnitt versucht const_cast
zu schummeln, kann es aber wirklich nicht: Während der Typ geändert wurde, ist tatsächliche Änderung nicht erlaubt : Die Zeichenfolge ist wirklich const
. Der Versuch, sie zu ändern, würde dazu führen, dass das Programm undefiniertes Verhalten zeigt.
Der Unterschied ist semantisch - ich. e. Gleicher generierter Code, gleiche Laufzeit ( const
ness ist sowieso ein reines Kompilierungskonstrukt), aber die beiden Konstrukte vermitteln eine etwas andere Bedeutung.
Die Idee ist, dass Sie mutable
für Variablen verwenden, die sich in der Klasse befinden, aber nicht den Zustand des Objekts darstellen. Das klassische Beispiel ist die aktuelle Position in einem Blob-Objekt. Navigieren im Blob zählt nicht als "Modifizieren" des Blobs in einer Weise, die wichtig ist. Wenn Sie mutable
verwenden, sagen Sie "diese Variable kann sich ändern, aber das Objekt ist immer noch dasselbe". Sie sagen, dass für diese spezielle Klasse const
-ness nicht bedeutet "alle Variablen sind eingefroren".
const_cast
bedeutet andererseits, dass Sie bestehende const-Korrektheit verletzen und hoffen, damit durchzukommen. Wahrscheinlich, weil Sie mit einer Drittanbieter-API arbeiten, die const
nicht respektiert (z. B. eine C-basierte Version der alten Schule).
Vereinfacht ausgedrückt deklariert eine Membervariable als mutable
den Schreibzugriff von jeder Konstantenmethode dieser Klasse ohne irgendeine andere spezielle Syntax. const_cast
muss dagegen immer dann ausgeführt werden, wenn Sie auf eine ansonsten konstante Variable schreiben wollen und diese Variable nicht einmal ein Klassenmitglied sein muss.
Sofern Sie den Schreibzugriff auf eine Membervariable nicht explizit zulassen möchten, wird die Verwendung von const_cast
in jedem Fall der Verletzung der const-Korrektheit bevorzugt, wenn Sie nur Ihre Absichten klar angeben.
Nebenbei bemerkt, const_cast kann auch verwendet werden, um den volatile
Modifikator hinzuzufügen oder zu entfernen.