Pregunta

Sé que hay pocos ponen en duda sobre la corrección const, donde se afirma que la declaración de una función y su definición no es necesario llegar a un acuerdo para parámetros de valor. Esto se debe a la constness de un parámetro de valor único que importa es el interior de la función. Esto está muy bien:

// header
int func(int i);

// cpp
int func(const int i) {
    return i;
}

Está haciendo esto realmente una buena práctica? Porque nunca he visto a nadie hacerlo. He visto esta cita (no estoy seguro de la fuente) en otros lugares esto se ha discutido:

  

"De hecho, para el compilador, la firma de la función es la misma tanto si se incluye este const delante de un parámetro de valor o no."

     

"Evitar const parámetros pase-por-valor en la declaración de funciones. Aún hacen la const parámetro en la definición de la misma función si no se modificará."

El segundo párrafo dice que no pone la const en la declaración. Asumo que esto es porque el constness de un parámetro de valor no tiene sentido como parte de una definición de interfaz. Es un detalle de implementación.

Sobre la base de esta recomendación, sino que también se recomienda para los valores del puntero de parámetros de puntero? (No tiene sentido en un parámetro de referencia, puesto que no se puede volver a asignar una referencia.)

// header
int func1(int* i);
int func2(int* i);

// cpp
int func1(int* i) {
    int x = 0;

    *i = 3; // compiles without error
    i = &x; // compiles without error

    return *i;
}
int func2(int* const i) {
    int x = 0;

    *i = 3; // compiles without error
    i = &x; // compile error

    return *i;
}

Resumen: Hacer parámetros de valor es útil para capturar algunos errores lógicos. ¿Es una mejor práctica? ¿Usted va al extremo de dejar la const del archivo de cabecera? Es tan útil a valores de puntero const? ¿Por qué o por qué no?

Algunas referencias:

C ++ const palabra clave - utilizar libremente de 'const' para los parámetros de función

Un ejemplo de cuando los parámetros de valor const son útiles:

bool are_ints_equal(const int i, const int j) {
    if (i = j) { // without the consts this would compile without error
        return true;
    } else {
        return false;
    }
    // return i = j; // I know it can be shortened
}
¿Fue útil?

Solución

Mi opinión sobre ella:

No es una mala idea, pero el problema es menor y su energía podría ser mejor gastado en otras cosas.

En su pregunta que proporciona un buen ejemplo de cuándo podría atrapar un error, pero en ocasiones también terminan haciendo algo como esto:

void foo(const int count ...)
{
   int temp = count;  // can't modify count, so we need a copy of it
   ++temp;

   /* ... */
}

Los pros y los contras son menores de cualquier manera.

Otros consejos

He leído muchas veces que lo que los parámetros de valor en una función const es una mala cosa que hacer porque es innecesaria.

Sin embargo, creo que es en ocasiones útil para mí como un cheque que mi aplicación no hace algo que no es mi intención (como en el ejemplo al final de su pregunta).

Así que, aunque no se puede añadir valor a la persona que llama, que hace a veces añadir un poco de valor para mí como un ejecutor, y no quita nada a la persona que llama. Por lo tanto, no veo mal uso de ella.

Por ejemplo, se me puede implementar una función C que lleva un par de punteros a un búfer - un puntero al comienzo, y un puntero al final. Voy a poner los datos en el búfer, pero desea asegurarse de que no rebasamiento final. Así que dentro de la función, existe un código que incrementar un puntero como estoy añadiendo datos en él. Haciendo que el puntero al final del búfer un parámetro const se asegurará de que no codifican un error que incrementa accidentalmente el puntero del límite final en lugar del puntero que realmente debería estar incrementando.

Así que una función fillarray con una firma como esta:

size_t fillArray( data_t* pStart, data_t* const pEnd);

me va a impedir que accidentalmente incrementar pEnd cuando me refiero a incrementar pStart. No es una gran cosa, pero estoy bastante seguro de que todos los que han programado para cualquier período de tiempo en C se ejecutará a través de un insecto tales.

Por desgracia, algunos compiladores (estoy mirando a ti, Sun CC!) Se diferencian de forma incorrecta entre los argumentos declarados const y cuáles no declarados así, y se puede obtener errores acerca de las funciones definidas.

Creo que esto depende de su estilo personal.

No añade ni resta nada a lo que los clientes pueden pasar a su función. En esencia es como una afirmación en tiempo de compilación. Si se le ayuda a saber que el valor no cambiará, seguir adelante y hacerlo, pero no veo una gran razón para que otros lo hagan.

Una de las razones puede ser que no hacerlo es que el const-dad del parámetro valor es un detalle de implementación que sus clientes no necesitan conocer. Si más tarde (a propósito) cambia su función de manera que lo que realmente cambia ese valor, será necesario cambiar el firma de su función, lo que obligará a sus clientes a volver a compilar.

Esto es similar a qué algunas personas recomiendan que no hay métodos virtuales públicos (las funciones virtuales-Ness es un detalle de implementación que deben ocultarse a los clientes), pero no estoy en ese campo en particular.

Si no hay palabra clave const presente; que significa valor de 'i' (que es de tipo const) no puede ser modificado. Si se cambia el valor de la 'i' en el interior del compilador función foo arrojará error: "

  

No se puede modificar objeto constante

Pero cambiar '* i' (es decir, * i = 3;) significa que no va a cambiar el valor de 'i', pero el valor de la dirección apuntada por 'i'

En realidad, la función const es apropiado para objetos grandes que no deben ser alteradas por función.

Todos tenemos que desenredar C de otro código ++ de vez en cuando. Y que el código de C ++ de otra persona es un completo desastre por definición:. D

Así que la primera cosa que siempre hago a descifrarlo (flujo de datos local y global) se pone const en cada definición de la variable hasta que el compilador se queja. Esto también significa argumentos de valor const-calificación, y lo que realmente ayuda a evitar las variables que han sido modificados en el medio de la función sin que yo lo notara ...

Así que realmente apreciar cuando esa otra persona tiene const todas partes (incluyendo los parámetros de valor): D

Me gusta la corrección const para situaciones como ésta:
void foo(const Bar &b) //I know b cannot be changed
{
//do something with b
}

Esto me permite utilizar b sin temor a modificarlo, pero no tiene que pagar el costo de un constructor de copia.

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