====== Const entfernen - const_cast ====== Ein ''const_cast'' wird wie folgt aufgebaut const_cast< TypVonObject_ohne_Const >( object ) Zurückgegeben wird das übergebene Objekt, der allerdings im Datentyp den ''[[cpp:const:]]''-Qualifizierer verloren hat. Ein Const-Cast ist eine legitimierte Notlösung. Gelegentlich stößt man auf alte Funktionen, die zwar noch benötigt werden, jedoch zu einer Zeit geschrieben wurden, als [[cpp:const:|Const-Correctness]] für die meisten Entwickler noch ein Fremdwort war. ===== fehlendes Const bei Parametern ===== Hat man Beispielsweise eine Funktion in einer alten Library wie ''int myStrLen( char * )'' und möchte diese nun verwenden, um die Länge eines ''const char *'' zu ermitteln: #include int myStrLen( char * str ) { int l = 0; while( *str++ ) l++; return l; } int main(int argc, char **argv) { char const * text = "Hallo Welt"; int length = myStrLen( text ); printf( "Der Text ist %d Zeichen lang\n", length ); return 0; } Dieser Quelltext liefert folgende Fehler: error: invalid conversion from `const char*' to `char*' error: initializing argument 1 of `int myStrLen(char*)' Hier wäre sicherlich der richtige Weg, die Funktion myStrLen anzupassen, aber nehmen wir an, wir wissen, dass sie das Objekt nicht verändert, doch wir haben den Quelltext nicht vorliegen, weil sie in einer gekauften Library liegt. Um dieses Programm zu kompilieren müssten wir nun entweder eine Kopie des Strings erstellen, was Zeitaufwendig wäre. Um dies zu vermeiden - wenn wir denn wissen, dass die Funktion die übergebenen Parameter nicht verändert - wurde ''const_cast'' erfunden. Unser Problem mit der ''myStrLen''-Funktion lässt sich mit einem ''const_cast'', wie folgt lösen: int main(int argc, char **argv) { char const * text = "Hallo Welt"; int length = myStrLen( const_cast< char * >( text ) ); printf( "Der Text ist %d Zeichen lang\n", length ); return 0; } ''const_cast'' muss den gleichen Datentyp zurückgegeben, dass das Objekt besitzt, lediglich der ''const''-Qualifizierer darf fehlen. Es ist also nicht möglich gleichzeitig ''const'' und den Datentyp zu verändern. In dem Fall sollte ''const_cast'' mit einem ''[[static|static_cast]]'' kombiniert werden, auch wenn ein [[c:cast|C-Style-Cast]] kürzer wäre. Nur mit dieser Ausführlichkeit lässt sich aus dem Quelltext herauslesen, was genau gemeint ist und die Hässlichkeit des Quelltextes an der Stelle markiert deutlich, dass hier etwas passiert, dem man Aufmerksamkeit schenken sollte, wenn man einen Fehler sucht. ===== fehlendes Const bei Const-Methoden ===== Es lassen sich so auch Methoden von Objekten aufrufen, die nicht als Const gekennzeichnet sind. Die Wahrscheinlichkeit, hier Fehler in ein Programm einzubauen steigt allerdings deutlich, denn wäre die Methode für einen const-Zugriff geeignet hätte ein guter Entwickler sie entsprechend markiert! #include class Value { int a; public: Value( int value ) : a( value ) {} int add( int b ) { return a+b; } }; int main(int argc, char **argv) { Value const v( 1 ); // Konstantes Objekt int result = v.add( 2 ); printf( "Ergebnis: %d\n", result ); return 0; } wird mit der Meldung error: passing `const Value' as `this' argument of `int Value::add(int)' discards qualifiers belohnt. (siehe auch [[c:faq:passing_const_discards_qualifiers|hier]]) Wenn wir sicher sein können, dass das Objekt nicht verändert wird und es nicht möglich ist, die Klasse ''Value'' zu verbessern, dann hilft der ''const_cast'', in dem wir uns eine Referenz auf das Objekt ohne den ''const''-Qualifizierer geben lassen: int result = const_cast< Value & >( v ).add( 2 ); ==== Die bessere Lösung ==== Besser wäre jedoch die Klasse ''Value'' zu verbessern und die Methode ''add'' zu einer [[cpp:const:def|Const-Methode]] zu ändern: int add( int b ) const { return a+b; } ===== Fazit ===== Hier zeigt sich sehr schön, dass ein Cast in der Regel nur einen Fehler an anderer Stelle kaschiert. Entsprechend selten, möglichst gar nicht, sollten Castings in den eigenen Quelltexten auftreten. Grundsätzlich lässt sich das Problem an der Überschrift ablesen: ''const'' fehlt beim Datentyp des Parameters einer Funktion oder Methode oder es fehlt das ''const'' bei der Methodendeklaration. Ein ''const_cast'' ist immer nur eine Notlösung, wenn man sich mit einer Library beschäftigten muss, die man nicht ändern kann. Ansonsten sollte man sich besser um die Ursache kümmern, statt Symptome zu behandeln.