after c++ syntax const

c++ - after - const int



C++ const keyword-use generosamente? (12)

Aquí hay algunos artículos geniales y un libro que encontré explicando las ventajas de usar const:

¿Te puedo proponer la siguiente máxima?

Si un objeto / variable puede ser calificado ha sido constante, debería serlo. En el peor de los casos, no le costará nada. En el mejor de los casos, documentará el rol del objeto / variable en su código y le permitirá al compilador la oportunidad de optimizar su código aún más.

Algunos compiladores se niegan a explotar el potencial de optimización con el uso de ''const'' y eso ha llevado a muchos expertos a descuidar el uso de parámetros constantes por valor cuando podría usarse. Esta práctica requiere más rigor, pero no será perjudicial. En el peor de los casos, no pierde nada, pero tampoco gana nada y, en el mejor de los casos, gana utilizando este método.

Para aquellos que no parecen entender la utilidad de una constante en un parámetro por valor de una función / método ... aquí hay un breve ejemplo que explica por qué:

.cpp

void WriteSequence(int const *, const int); int main() { int Array[] = { 2, 3, 4, 10, 12 }; WriteSequence(Array, 5); } #include <iostream> using std::cout; using std::endl; void WriteSequence(int const *Array, const int MAX) { for (int const * i = Array; i != Array + MAX; ++i) cout << *i << endl; }

¿Qué pasaría si yo eliminara la const delante de int MAX y escribiera MAX + 1 adentro de esta manera?

void WriteSequence(int Array[], int MAX) { MAX += MAX; for (int * i = Array; i != Array + MAX; ++i) cout << *i << endl; }

Bueno, tu programa se estrellaría! Ahora, ¿por qué alguien escribiría "MAX + = MAX;" ? Tal vez un error humano, tal vez el programador no se sentía bien ese día o tal vez el programador simplemente no sabía cómo escribir código C / C ++. ¡Si hubieras tenido const, el código ni siquiera habría sido compilado!

El código de seguridad es un buen código y no cuesta nada agregar "const" cuando lo tenga.

Aquí hay una respuesta de una publicación diferente para una pregunta muy similar:

"const no tiene sentido cuando el argumento se pasa por valor ya que no modificará el objeto de la persona que llama".

Incorrecto.

Se trata de auto-documentar su código y sus suposiciones.

Si su código tiene muchas personas trabajando en él y sus funciones no son triviales, entonces debe marcar "const" cualquiera y todo lo que pueda. Al escribir un código de fuerza industrial, siempre debe asumir que sus compañeros de trabajo son psicópatas que intentan conseguir lo que pueden (especialmente porque en el futuro es usted mismo).

Además, como alguien mencionó anteriormente, podría ayudar al compilador a optimizar un poco las cosas (aunque es una posibilidad remota).

Aquí está el enlace: answer .

En las siguientes funciones de C ++:

void MyFunction(int age, House &purchased_house) { ... } void MyFunction(const int age, House &purchased_house) { ... }

¿Cual es mejor?

En ambos, la ''edad'' se pasa por valor. Me pregunto si la palabra clave ''const'' es necesaria: me parece redundante, pero también es útil (como una indicación adicional de que la variable no cambiará).

¿Alguien tiene alguna opinión sobre cuál (si alguno) de los anteriores es mejor?


Bueno, como ya se ha dicho, desde el punto de vista del lenguaje C ++, la const anterior no tiene ningún efecto en la firma de la función, es decir, el tipo de función sigue siendo el mismo, independientemente de si la const está allí o no. El único efecto que tiene en el nivel del lenguaje C ++ abstracto es que no puede modificar este parámetro dentro del cuerpo de la función.

Sin embargo, en el nivel inferior, el modificador const aplicado al valor del parámetro puede tener algunos beneficios de optimización, dado un compilador suficientemente inteligente. Considere dos funciones con el mismo conjunto de parámetros (por simplicidad)

int foo(const int a, const double b, const long c) { /* whatever */ } void bar(const int a, const double b, const long c) { /* whatever */ }

Digamos que en algún lugar del código se llaman así:

foo(x, d, m); bar(x, d, m);

Normalmente, los compiladores preparan el marco de pila con argumentos antes de llamar a una función. En este caso, la pila normalmente se preparará dos veces: una para cada llamada. Pero un compilador inteligente podría darse cuenta de que, dado que estas funciones no cambian sus valores de parámetros locales (declarados con const ), el conjunto de argumentos preparado para la primera llamada se puede reutilizar de forma segura para la segunda llamada. De esta forma puede preparar la pila solo una vez.

Esta es una optimización bastante rara y oscura, que solo puede funcionar cuando se conoce la definición de la función en el punto de la llamada (ya sea la misma unidad de traducción o un compilador avanzado que optimiza globalmente), pero a veces puede valer la pena mencionarlo.

No es correcto decir que es "sin valor" o "no tiene efecto", aunque con un compilador típico este podría ser el caso.

Otra consideración que vale la pena mencionar es de diferente naturaleza. Existen estándares de codificación por ahí, que requieren que los codificadores no cambien los valores de los parámetros iniciales, ya que en "no usar parámetros como variables locales ordinarias, los valores de los parámetros deben permanecer sin cambios en toda la función". Esto tiene sentido, ya que a veces hace que sea más fácil determinar qué valores de parámetros se dieron originalmente a la función (mientras está en el depurador, dentro del cuerpo de la función). Para ayudar a hacer cumplir este estándar de codificación, las personas pueden usar especificadores const en los valores de los parámetros. Si vale la pena o no es una pregunta diferente ...


Debería usar const en un parámetro si (y solo si) lo usaría en cualquier otra variable local que no se modificará:

const int age_last_year = age - YEAR;

A veces es útil marcar constantes de variables locales siempre que sea posible, ya que significa que puede mirar la declaración y saber que ese es el valor, sin pensar en el código intermedio. Puede cambiarlo fácilmente en el futuro (y asegúrese de no haber roto el código en la función, y tal vez cambie el nombre de la variable si ahora representa algo ligeramente diferente, que es modificable, a diferencia de la versión anterior no cambiante). cosa).

En contra de eso, hace que el código sea más detallado, y en una función corta es casi siempre muy obvio qué variables cambian y cuáles no.

Entonces, ya sea:

void MyFunction(const int age, House &purchased_house) { const int age_last_year = age - YEAR; }

o:

void MyFunction(int age, House &purchased_house) { int age_last_year = age - YEAR; }


Esto, en mi humilde opinión, es un uso excesivo. Cuando dice "const. Edad, ...", lo que realmente dice es "no se puede cambiar ni la copia local dentro de su función". Lo que usted hace es hacer que el código del programador sea menos legible al forzarlo a usar otra copia local cuando quiera cambiar la edad / pasarla por referencia no constante.

Cualquier programador debe estar familiarizado con la diferencia entre pasar por referencia y pasar por valor, al igual que cualquier programador debe entender ''const''.


La segunda variante es mejor. En el primero se puede cambiar accidentalmente la edad variable.


No solo indica que no cambiará, evitará que su código piense que puede y se detectará en el momento de la compilación.


Primero, es solo un detalle de la implementación, y si coloca constantes allí, no lo ponga en el conjunto de declaración (encabezado). Solo ponlo en el archivo de implementación:

// header void MyFunction(int age, House &purchased_house); // .cpp file void MyFunction(const int age, House &purchased_house); { ... }

Si un parámetro está o no en una definición es puramente un detalle de implementación, y no debe ser parte de la interfaz.

No he visto este tipo de cosas a menudo, y tampoco hago esto. Tener el parámetro const me confundiría más a menudo que a la ayuda, ya que inmediatamente haría un patrón de coincidencia en el fallo para "const int & age" :) Por supuesto, la cuestión es completamente diferente de tener const en otro nivel:

// const is a *good* thing here, and should not be removed, // and it is part of the interface void MyFunction(const string &name, House &purchased_house); { ... }

En este caso, la constante afectará si la función puede cambiar el argumento de la persona que llama. Se debe utilizar Const en este sentido tan a menudo como sea posible, ya que puede ayudar a garantizar la corrección del programa y mejorar la autodocumentación del código.


Recomiendo leer Herb Sutter. C ++ excepcional . Hay un capítulo "Const-Correctness".

"De hecho, para el compilador, la firma de la función es la misma, ya sea que incluya esta constante delante de un parámetro de valor o no".

Significa que esta firma.

void print(int number);

es efectivamente lo mismo que esto:

void print(int const number);

Entonces, para el compilador no hay diferencia en cómo declaras una función. Y no puede sobrecargarla colocando la palabra clave const delante de un parámetro de paso por valor.

Lea más, lo que Herb Sutter recomienda:

"Evite los parámetros const de paso por valor en las declaraciones de función. Aún así, haga que el parámetro const en la definición de la misma función si no se modifica".

Recomienda evitar esto:

void print(int const number);

Porque esa const es confusa, verbosa y redundante.

Pero en la definición, debes hacer eso (si no cambias el parámetro):

void print(int const number) { // I don''t want to change the number accidentally here ... }

Por lo tanto, se asegurará de que incluso después de las 1000 líneas del cuerpo de la función siempre tenga el número intacto. El compilador le prohibirá pasar el número como una referencia no constante a otra función.


Tener un tipo primitivo que se pasa por valor const no tiene ningún valor. Pasar una constante a una función es generalmente útil como un contrato con la persona que llama que la función no cambiará el valor. En este caso, debido a que la int se pasa por valor, la función no puede realizar ningún cambio que sea visible fuera de la función.

Por otro lado, las referencias y los tipos de objetos no triviales siempre deben usar const si no se van a realizar cambios en el objeto. En teoría, esto podría permitir cierta optimización, pero la gran victoria es el contrato que mencioné anteriormente. La desventaja es, por supuesto, que puede hacer que su interfaz sea mucho más grande, y que sea una tarea difícil de adaptar a un sistema existente (o con una API de terceros que no usa const en todas partes).


Una de las ventajas de usar const es que no puede cambiar accidentalmente el valor de la age en medio de MyFunction (en el caso de que haya olvidado que no fue pasado por referencia). Una "desventaja" es que no puede reciclar age con código como foo.process(++age); .


Usted tiene razón, el único propósito de la "edad constante" es que la edad no se puede cambiar. Sin embargo, esto puede ser muy confuso para la mayoría de los programadores. Por lo tanto, si este enfoque no se usa ampliamente en su código, le aconsejaría que omita const.


Vea Meyers y ''Effective C ++'' en esto, y use const abundantemente, especialmente con semántica de paso por referencia.

En este caso de variables atómicas, la eficiencia no importa, pero la claridad del código aún se beneficia.