2011-10-27 18 views
38

¿Qué significa const en el calificador de "nivel superior" en C++?¿Qué son los clasificadores const de nivel superior?

¿Y cuáles son los otros niveles?

Por ejemplo:

int const *i; 
int *const i; 
int const *const i; 
+3

ejemplos, por favor? – bmargulies

+0

No sé a qué se refiere con ejemplos, pero agregué algunos calificadores const con los que estoy familiarizado. – user103214

+3

Ver también [¿Dónde está la definición de 'cv-qualifiers' de nivel superior en el estándar C++ 11?] (Http://stackoverflow.com/q/24676824/1708801) –

Respuesta

49

A const calificador de nivel superior afecta el objeto mismo. Otros son solo relevantes con punteros y referencias. No hacen el objeto const, y solo previenen la modificación a través de una ruta usando el puntero o la referencia . Por lo tanto:

char x; 
char const* p = &x; 

Esto no es un const de nivel superior, y ninguno de los objetos es inmutable. La expresión *p no se puede usar para modificar x, pero otras expresiones pueden ser; x no es const. Para el caso

*const_cast<char*>(p) = 't' 

es legal y está bien definido.

Pero

char const x = 't'; 
char const* p = &x; 

Esta vez, no es una constante de nivel superior en x, por lo x es inmutable. No se permite la expresión para cambiarlo (incluso si se usa const_cast). El compilador puede poner x en la memoria de solo lectura, y puede suponer que el valor de x nunca cambia, independientemente de lo que otro código pueda hacer.

Para dar el puntero de nivel superior const, usted escribiría:

char x = 't'; 
char *const p = &x; 

En este caso, p apuntará a x siempre; cualquier intento de cambiar este es un comportamiento indefinido (y el compilador puede poner p en la memoria de solo lectura, o asumir que *p se refiere a x, independientemente de cualquier otro código).

+3

Muy claro, gracias :) – Seb

+6

Otro punto: al escribir funciones, los calificadores de nivel superior de los argumentos se descartan. Esto significa que 'void foo (char const)' y 'void foo (char)' son la misma función (y de hecho pueden intercambiarse). El razonamiento es que dado que el argumento se toma por copia, a la persona que llama no le importa si la copia se puede modificar o no, por lo que es transparente para ella. –

+7

@MatthieuM. Buen punto, aunque no exactamente como se dijo. Los calificadores de nivel superior se ignoran en una declaración y en el tipo de la función. En la definición, sin embargo, todavía se comportan como de costumbre dentro de la función. (Los calificadores de nivel superior también son ignorados por 'typeid' y parámetros de plantilla, cuando se combinan excepciones para capturar, y probablemente en otros casos lo he olvidado. En la práctica, tampoco tienen efecto en los valores de devolución de tipo no de clase) –

10

int *const i pone const en el nivel superior, mientras que int const *i no lo hace.

El primero dice que el puntero i en sí mismo es inmutable, mientras que el segundo dice que la memoria a la que apunta el puntero es inmutable.

Siempre que aparezca const inmediatamente antes o después del tipo del identificador, se considera un calificador de nivel superior.

+0

Respuesta excelente y clara. PD 'int const * i' es igual a' const int * i' (todos son const de bajo nivel). Yo uso 'const int * i' (bajo nivel) para distinguir su nivel de const más a menudo de' int * const i' (nivel superior). – dotslash

5

La forma en que se explicó para mí, dado:

[const] TYPE * [const] VARIABLE 

VARIABLE se utiliza para apuntar a datos de tipo TIPO través de *VARIABLE

Dibujar una línea a través de la * o múltiple * s

  1. Si hay una const a la izquierda del * se aplica a los datos y los datos no se puede cambiar: *VARIABLE no pueden ser asignados, excepto en la inicialización
  2. Si hay una const a la derecho del * se aplica a la VARIABLE y cuáles son los puntos VARIABLE a no se pueden cambiar: VARIABLE no se puede asignar, excepto en initiali zación

Así:

  |    left right 
int  *  i1; 
      |    no no  can change *i1 and i1 

int const *  i2;  
      |    yes no  cannot change *i2 but can change i2 

int  * const i3; 
      |    no yes can change *i3 but i3 cannot be changed 

int const * const i4; 
      |    yes yes cannot change *i4 or i4 
+0

'const' se une a la izquierda. a menos que no haya nada a la izquierda, se une a la derecha – sp2danny

Cuestiones relacionadas