2012-07-12 11 views
8

Desde mi entender, mutable cancela la constness de una variableconst_cast VS mutable? ¿alguna diferencia?

Class A { 
    void foo() const { 
    m_a = 5; 
} 
mutable int m_a; 
}; 

Pero también const_cast:

void print (char * str) 
{ 
    cout << str << endl; 
} 

int main() { 
    const char * c = "this is a line"; 
    print (const_cast<char *> (c)); 
    return 0; 
} 

Por lo tanto, lo que cambia el uno del otro?

Gracias

Respuesta

16

const_cast no se puede cancelar la constness de un objeto. const_cast solo puede eliminar la constness de un ruta de acceso a un objeto. La ruta de acceso es un puntero o una referencia a un objeto. Eliminar la constness de la ruta de acceso no tiene ningún efecto en el objeto en sí. Incluso si usa const_cast para eliminar la constitud de la ruta de acceso, eso aún no necesariamente le da permiso para modificar el objeto. Si puedes hacerlo o no depende del objeto en sí. Si es const, no está permitido modificarlo y cualquier intento de hacerlo dará como resultado un comportamiento indefinido.

Por ejemplo, esto ilustra el uso previsto de const_cast

int i = 5; // non-constant object 
    const int *p = &i; // `p` is a const access path to `i` 

    // Since we know that `i` is not a const, we can remove constness... 
    int *q = const_cast<int *>(p); 
    // ... and legally modify `i` 
    *q = 10; 
    // Now `i` is 10 

La única razón de lo anterior es legal y válido es el hecho de que i es en realidad un no constante objeto , y sabemos al respecto .

Si el objeto original era muy constante, entonces el código anterior produciría un comportamiento indefinido:

const int j = 5; // constant object 
    const int *p = &j; // `p` is a const access path to `j` 

    int *q = const_cast<int *>(p); // `q` is a non-const access path to `j` 
    *q = 10; // UNDEFINED BEHAVIOR !!! 

lenguaje C++ no permite modificar los objetos constantes y const_cast es totalmente impotente aquí, independientemente de cómo se usa eso.

mutable es algo completamente diferente. mutable crea un archivo de datos que puede modificarse legalmente incluso si el objeto que lo contiene se declara const. En ese sentido, mutable le permite modificar [algunas partes designadas de] objetos constantes. const_cast, por otro lado, no puede hacer nada de eso.

1

La diferencia es semántica - i. mi. mismo código generado, los mismos resultados de tiempo de ejecución (const ness es una construcción puramente de tiempo de compilación de todos modos), pero las dos construcciones transmiten un significado ligeramente diferente.

La idea es que use mutable para las variables que están en la clase, pero que no constituyen el estado del objeto. El ejemplo clásico es la posición actual en un objeto blob. Navegar en el blob no cuenta como "modificar" el blob de una manera que importe. Al usar mutable, dices "esta variable puede cambiar, pero el objeto sigue siendo el mismo". Estás diciendo que para esta clase en particular, const -ness no significa "todas las variables están congeladas".

const_cast, por otro lado, significa que está violando la exactitud de la constidad existente y espera salirse con la suya. Probablemente porque está trabajando con una API de un tercero que no respeta const (por ejemplo, una versión antigua basada en C).

4

La diferencia es que const_cast no puede hacer trampa, pero mutable es una excepción a las reglas.

En el primer fragmento m_a es mutable, y por lo tanto una excepción a la regla de que no se pueden modificar los miembros de datos en las funciones de miembro const.

En el segundo fragmento, const_cast trata de engañar, pero en realidad no puede: mientras que el tipo ha cambiado, modificación real no está permitido: la cadena es verdaderamente const. Si intenta modificarlo, el programa exhibirá un comportamiento indefinido.

0

En pocas palabras, declarar un miembro variable como mutable lo hace accesible a escritura desde cualquier método constante de esa clase sin ninguna otra sintaxis especial. const_cast por otro lado tiene que realizarse siempre que desee acceso de escritura a una variable de lo contrario constante, y esa variable ni siquiera tiene que ser un miembro de la clase.

A menos que desee permitir explícitamente el acceso de escritura a una variable miembro, se recomienda usar const_cast en todos los casos de violación de const corrección, aunque solo sea para indicar claramente sus intenciones.

En una nota lateral, const_cast también se puede utilizar para agregar o eliminar el modificador volatile.

Cuestiones relacionadas