Para empezar, probablemente sepa que constpuede usarse para hacer que los datos de un objeto o un puntero no sean modificables o ambos.
const Object* obj; // can't change data
Object* const obj; // can't change pointer
const Object* const obj; // can't change data or pointer
Sin embargo, también puede usar la sintaxis:
Object const *obj; // same as const Object* obj;
Lo único que parece importar es qué lado del asterisco coloca la constpalabra clave. Personalmente, prefiero poner consta la izquierda del tipo para especificar que sus datos no se pueden modificar, ya que creo que se lee mejor en mi mentalidad de izquierda a derecha, pero ¿qué sintaxis vino primero?
Más importante aún, ¿por qué hay dos formas correctas de especificar constdatos y en qué situación preferiría o necesitaría una sobre la otra si la hubiera?
Editar:
Parece que esta fue una decisión arbitraria cuando el estándar de cómo los compiladores deberían interpretar las cosas fue redactado mucho antes de que yo naciera. Dado que constse aplica a lo que está a la izquierda de la palabra clave (¿de manera predeterminada?) Supongo que pensaron que no era perjudicial agregar "accesos directos" para aplicar palabras clave y calificadores de tipo de otras maneras, al menos hasta el momento en que la declaración cambie analizando un * o & ...
Este fue el caso también en C, entonces supongo.

constdespués del tipo, por ejemplo, en#define MAKE_CONST(T) T constlugar de#define MAKE_CONST(T) const Tpara queMAKE_CONST(int *)se expanda correctamente enint * constlugar deconst int *.Respuestas:
Esencialmente, la razón por la cual la posición de los
constespecificadores antes de un asterisco no importa es que Kernighan y Ritchie definieron la gramática C de esa manera.La razón por la que definieron la gramática de esta manera era probable que su compilador de C analizara la entrada de izquierda a derecha y terminara de procesar cada token a medida que lo consumía. El consumo del
*token cambia el estado de la declaración actual a un tipo de puntero. Encuentroconstdespués*significa que elconstcalificador se aplica a una declaración de puntero; encontrarlo antes de que el*calificador se aplique a los datos apuntados.Debido a que el significado semántico no cambia si el
constcalificador aparece antes o después de los especificadores de tipo, se acepta de cualquier manera.Un tipo similar de caso surge al declarar punteros de función, donde:
void * function1(void)declara una función que devuelvevoid *,void (* function2)(void)declara un puntero de función a una función que devuelvevoid.Nuevamente, lo que hay que notar es que la sintaxis del lenguaje admite un analizador de izquierda a derecha.
fuente
*analizador del compilador no sepa que es puntero, por lo tanto, es constante para el valor de los datos. Después * está relacionado con el puntero constante. Brillante. Y finalmente explica por qué puedo hacerloconst chartan bien comochar const.constque siempre venga después de lo que está calificando ... exactamente para que siempre pueda terminar de procesar el constante inmediatamente después de consumirlo. Así que esto parece ser un argumento para prohibir West-Const, en lugar de permitirlo.++operador? "La oración", en mi humilde opinión, me ayudó a darme cuenta de que no había otra razón en particular que no fuera porque podían hacerlo. Tal vez harían una elección diferente hoy / tal vez no.La regla es:
Prefiero usar const a la derecha de la cosa para ser const solo porque es la forma "original" en que se define const.
Pero creo que este es un punto de vista muy subjetivo.
fuente
Object const *es un puntero a un objeto const. Si coloca elconstde la izquierda, se leería como un puntero a un Objeto que es constante, que realmente no fluye muy bien.constque no es una clase de almacenamiento, pero las personas no son analizadores).Prefiero la segunda sintaxis. Me ayuda a hacer un seguimiento de 'qué' es constante leyendo la declaración de tipo de derecha a izquierda:
fuente
Object const* constno lo esconst const Object*. "const" no puede estar a la izquierda, excepto en el caso especial donde tanta gente lo adora. (Ver Heath arriba.)El orden de las palabras clave en una declaración no es tan fijo. Hay muchas alternativas para "el único orden verdadero". Me gusta esto
o debería ser
??
fuente
decl-specifier-seqes una secuencia dedecl-specifiers. No hay un orden dado por la gramática, y el número de ocurrencias para cada palabra clave está limitado solo por algunas reglas semánticas (puede tener unoconstpero doslong:-)unsignedes un tipo, igual queunsigned intyint unsigned.unsigned longes otro tipo, igual queunsigned long intyint long unsigned. ¿Ves el patrón?;). OK, graciasstatical revoltijo de palabras, pero solo recientemente los compiladores se quejaron de questaticdebe ser lo primero.La primera regla es usar el formato que requieran sus estándares de codificación locales. Después de eso: poner el
constfrente lleva a un sinfín de confusión cuando están involucrados typedefs, por ejemplo:Si su estándar de codificación permite typedef's de punteros, entonces realmente debería insistir en poner la constante después del tipo. En todos los casos, pero cuando se aplica al tipo, const debe seguir a lo que se aplica, por lo que la coherencia también argumenta a favor del const posterior. Pero las pautas de codificación locales prevalecen sobre todas estas; La diferencia no suele ser lo suficientemente importante como para volver atrás y cambiar todo el código existente.
fuente
const std::string::const_iteratorbuena medida;)const IntPtr p1significar que no sea "puntero entero constante" (es decir, "puntero constante a entero")? Nadie en su sano juicio, incluso sin saber cómoIntPtrse define, pensaría quep1es mutable. Y para el caso, ¿por qué alguien asumiría incorrectamente que*p1es inmutable? Además, poner la constante en cualquier otro lugar (p. Ej.IntPtr const p1) No cambia la semántica en absoluto.std::vector<T>::const_iterator, donde no es el iterador el que es constante, sino a lo que apunta).Hay razones históricas por las que se acepta izquierda o derecha. Stroustrup había agregado constante a C ++ en 1983 , pero no llegó a C hasta C89 / C90.
En C ++ hay una buena razón para usar siempre const a la derecha. Serás coherente en todas partes porque las funciones miembro const deben declararse de esta manera:
fuente
const int& getInt();int& const getInt();int const& getInt();es mejor que el equivalente,const int& getInt();mientrasint& const getInt();que compararlo es redundante (las referencias ya son constantes) aunque legales y generalmente darán una advertencia. De todos modos, const en una función miembro cambia elthispuntero en la función deFoo* constaFoo const* const.consten una función miembro no significa en absoluto lo mismo, ¿o esvoid set(int)&;algún tipo de referencia a una función?