ejemplo dev define constantes c++ arguments const

c++ - dev - ¿Cuándo usar la referencia const y const en la función args?



constantes en c (4)

La principal ventaja de la referencia de const sobre el puntero de const es la siguiente: está claro que el parámetro es obligatorio y no puede ser NULL. Y viceversa, si veo un indicador de const, inmediatamente asumo que la razón para que no sea una referencia es que el parámetro podría ser NULL.

Al escribir una función de C ++ que tiene argumentos que se le están pasando, desde mi entendimiento, const debería usarse siempre si puede garantizar que el objeto no se cambiará o un puntero de const si el indicador no se cambiará.

¿Cuándo más se aconseja esta práctica?

¿Cuándo utilizaría una referencia constante y cuáles son las ventajas de pasarla a través de un puntero, por ejemplo?

¿Qué pasa con este void MyObject::Somefunc(const std::string& mystring) ¿Cuál sería el punto de tener una cadena de const si una cadena de hecho ya es un objeto inmutable?


La regla general es, use const siempre que sea posible, y solo omítala si es necesario. const puede permitir que el compilador optimice y ayuda a sus compañeros a comprender cómo se pretende utilizar su código (y el compilador detectará un posible mal uso).

En cuanto a su ejemplo, las cadenas no son inmutables en C ++. Si entrega una referencia no const a una cadena a una función, la función puede modificarla. C ++ no tiene el concepto de inmutabilidad incorporado en el lenguaje, solo puede emularlo usando encapsulación y const (que nunca será a prueba de balas).

Después de pensar el comentario de @Eamons y leer algunas cosas, estoy de acuerdo en que la optimización no es la razón principal para usar const . La razón principal es tener el código correcto.


Las preguntas se basan en algunas suposiciones incorrectas, por lo que no son realmente significativas.

std::string no modela valores de cadena inmutables. Modela valores mutables.

No hay tal cosa como una "referencia constante". Hay referencias a objetos const . La distinción es sutil pero importante.

La const nivel superior para un argumento de función solo tiene sentido para la implementación de una función, no para una declaración pura (donde el compilador no la tiene en cuenta). No le dice nada a la persona que llama. Es solo una restricción en la implementación. Por ejemplo, int const tiene mucho sentido como tipo de argumento en una declaración pura de una función. Sin embargo, la const en std::string const& no es de nivel superior.

Pasar por referencia a const evita la copia ineficiente de datos. En general, para un argumento que pasa datos a una función, usted pasa elementos pequeños (como un int ) por valor, y elementos potencialmente más grandes por referencia a const . En el código de máquina, la referencia a const se puede optimizar o se puede implementar como un puntero. Por ejemplo, en Windows de 32 bits, un int es de 4 bytes y un puntero es de 4 bytes. Por lo tanto, el tipo de argumento int const& no reduciría la copia de datos, pero podría, con un compilador de mentalidad simple, introducir una dirección indirecta adicional, lo que significa una ligera ineficiencia, por lo tanto, la distinción pequeña / grande.

Salud y salud,


Preguntar si agregar const es la pregunta incorrecta, desafortunadamente.

Compara la referencia no constante para pasar un puntero no constante

void modifies(T &param); void modifies(T *param);

Este caso es principalmente sobre estilo: ¿quieres que la llamada se vea como call(obj) o call(&obj) ? Sin embargo, hay dos puntos donde la diferencia importa. Si desea poder pasar nulo, debe usar un puntero. Y si está sobrecargando operadores, no puede usar un puntero en su lugar.

Comparar const ref a por valor

void doesnt_modify(T const &param); void doesnt_modify(T param);

Este es el caso interesante. La regla de oro es que los tipos "baratos para copiar" se pasan por valor, generalmente son tipos pequeños (pero no siempre), mientras que otros se pasan por const. Ref. Sin embargo, si necesita hacer una copia dentro de su función independientemente, debe pasar por valor . (Sí, esto expone un poco de detalles de implementación. C''est le C ++. )

Compare el puntero const con la sobrecarga no modificable

void optional(T const *param=0); // vs void optional(); void optional(T const &param); // or optional(T param)

Esto está relacionado con el caso de no modificación anterior, excepto que pasar el parámetro es opcional. Aquí hay la menor diferencia entre las tres situaciones, así que elija la que le haga la vida más fácil. Por supuesto, el valor predeterminado para el puntero no constante depende de usted.

Const por valor es un detalle de implementación

void f(T); void f(T const);

¡Estas declaraciones son en realidad exactamente la misma función! Cuando se pasa por valor, const es puramente un detalle de implementación. Pruébalo:

void f(int); void f(int const) {/*implements above function, not an overload*/} typedef void C(int const); typedef void NC(int); NC *nc = &f; // nc is a function pointer C *c = nc; // C and NC are identical types