static_cast cast c++ casting const-cast

c++ - static_cast - static cast



¿Es const_cast seguro? (7)

Estás destruyendo cualquier posibilidad de seguridad de hilos, si comienzas a modificar cosas que el compilador creía que eran const.

No puedo encontrar mucha información sobre const_cast . La única información que pude encontrar (en Stack Overflow) es:

El const_cast<>() se usa para agregar / eliminar const (ness) (o volátil-ness) de una variable.

Esto me pone nervioso ¿Podría el uso de un const_cast causar un comportamiento inesperado? ¿Entonces qué?

Alternativamente, ¿cuándo está bien usar const_cast ?


La respuesta corta es no, no es seguro.

La respuesta larga es que si sabes lo suficiente como para usarlo, entonces debería ser seguro.

Cuando estás emitiendo, lo que básicamente dices es: "Sé algo que el compilador no sabe". En el caso de const_cast, lo que está diciendo es: "Aunque este método tiene una referencia o puntero no const, sé que no cambiará el parámetro que lo paso".

Entonces, si realmente sabes lo que afirmas saber al usar el elenco, está bien usarlo.


Me resulta difícil creer que esa es la única información que puedes encontrar sobre const_cast. Citando del segundo hit de Google :

Si descarta la constness de un objeto que se ha declarado explícitamente como const e intenta modificarlo, los resultados no están definidos.

Sin embargo, si descarta la constness de un objeto que no ha sido explícitamente declarado como const, puede modificarlo de forma segura.


const_cast es seguro solo si estás lanzando una variable que originalmente no era const . Por ejemplo, si tienes una función que toma un parámetro de un const char * , y pasas un char * modificable, es seguro const_cast ese parámetro a un char * y modificarlo. Sin embargo, si la variable original era de hecho const , entonces el uso de const_cast dará como resultado un comportamiento indefinido.

void func(const char *param, size_t sz, bool modify) { if(modify) strncpy(const_cast<char *>(param), sz, "new string"); printf("param: %s/n", param); } ... char buffer[16]; const char *unmodifiable = "string constant"; func(buffer, sizeof(buffer), true); // OK func(unmodifiable, strlen(unmodifiable), false); // OK func(unmodifiable, strlen(unmodifiable), true); // UNDEFINED BEHAVIOR


Lo que Adam dice Otro ejemplo donde const_cast puede ser útil:

struct sample { T& getT() { return const_cast<T&>(static_cast<const sample*>(this)->getT()); } const T& getT() const { /* possibly much code here */ return t; } T t; };

Primero agregamos const al tipo al que apunta, luego llamamos a la versión const de getT , y luego eliminamos const del tipo de devolución, que es válido ya que t debe ser no const (de lo contrario, la versión no const de getT no podría haber sido llamado). Esto puede ser muy útil si tiene un cuerpo de función grande y desea evitar el código redundante.


#include <iostream> using namespace std; void f(int* p) { cout << *p << endl; } int main(void) { const int a = 10; const int* b = &a; // Function f() expects int*, not const int* // f(b); int* c = const_cast<int*>(b); f(c); // Lvalue is const // *b = 20; // Undefined behavior // *c = 30; int a1 = 40; const int* b1 = &a1; int* c1 = const_cast<int*>(b1); // Integer a1, the object referred to by c1, has // not been declared const *c1 = 50; return 0; }

fuente: http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fkeyword_const_cast.htm


Puedo pensar en dos situaciones donde const_cast es seguro y útil (puede haber otros casos válidos).

Una es cuando tienes una instancia, referencia o puntero const, y quieres pasar un puntero o referencia a una API que no es const-correct, pero que estás CERTE no modificará el objeto. Puede const_cast el puntero y pasarlo a la API, confiando en que realmente no cambiará nada. Por ejemplo:

void log(char* text); // Won''t change text -- just const-incorrect void my_func(const std::string& message) { log(const_cast<char*>(&message.c_str())); }

La otra es si está usando un compilador anterior que no implementa ''mutable'', y desea crear una clase que sea const lógica pero no const bitwise. Puede const_cast ''this'' dentro de un método const y modificar miembros de su clase.

class MyClass { char cached_data[10000]; // should be mutable bool cache_dirty; // should also be mutable public: char getData(int index) const { if (cache_dirty) { MyClass* thisptr = const_cast<MyClass*>(this); update_cache(thisptr->cached_data); } return cached_data[index]; } };