Pregunta

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

El const_cast<>() se utiliza para agregar o quitar const(ness) (o volátiles-ness) de una variable.

Esto me pone nervioso.Podría usar un const_cast provocar un comportamiento inesperado?Si es así, ¿qué?

Alternativamente, cuando está bien usar const_cast?

¿Fue útil?

Solución

const_cast es seguro sólo si estás lanzando una variable que fue en un principio noconst.Por ejemplo, si tiene una función que toma un parámetro de un const char *, y pasa en un modificables char *, es seguro const_cast que parámetro a un char * y modificarlo.Sin embargo, si la variable original era en realidad const, a continuación, utilizando const_cast va a resultar en 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

Otros consejos

No puedo pensar en dos situaciones en las que const_cast es segura y útil (puede haber otros casos válidos).

Uno es cuando se tiene una constante ejemplo, la referencia o puntero, y desea pasar un puntero o referencia a una API que no es const-corrección, pero que está seguro de que no va a modificar el objeto. Puede const_cast el puntero y pasarlo a la API, confiando en que en realidad no va a 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 que si estás usando un compilador de más edad que no implementa 'mutable', y que desea crear una clase que es, lógicamente, pero no const const bit a bit. Puede const_cast 'esto' dentro de un método const y modificar los 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];
    }
};

Me resulta difícil creer que ese es el solamente información que podría encontrar sobre const_cast. Citando de la segunda Google golpeó :

  

Si desecharon la constness de una   objeto que ha sido explícitamente   declarado como const, y tratar de   modificarlo, los resultados no están definidos.

     

Sin embargo, si se desecharon la   constness de un objeto que no tiene   declarada explícitamente como const, se   puede modificar de forma segura.

¿Qué dice Adam. Otro ejemplo en el que 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;
};

En primer lugar, añadimos const al tipo de puntos de this, entonces llamamos a la versión const de getT, y luego eliminamos const del tipo de retorno, que es válida desde t debe ser no constante ( de lo contrario, la versión no constante de <=> no podría haber sido llamado). Esto puede ser muy útil si tiene un cuerpo grande y la función que desea evitar código redundante.

La respuesta corta es no, no es seguro.

La respuesta larga es que si usted sabe lo suficiente como para usarlo, entonces debe ser seguro.

Cuando estás fundición, lo que está diciendo en esencia, es decir, "Yo sé algo que el compilador no sabe." En el caso de const_cast, lo que está diciendo es: "A pesar de que este método toma en una referencia o puntero no constante, sé que no va a cambiar el parámetro lo paso."

Así que si no sabe realmente lo que está reclamando a conocer en el uso del molde, entonces está bien para usarlo.

Usted está destruyendo cualquier posibilidad al hilo de seguridad, si se inicia la modificación de las cosas que el compilador pensaba que eran const.

#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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top