Mismo objeto que constante y no constante, ¿qué debo suponer para comportarme correctamente?
-
20-12-2019 - |
Pregunta
tengo una función de la forma
return_type function(const argument_type & a, argument_type & b);
Si se pasa el mismo objeto como a
y b
, ¿puedo continuar con la función (y potencialmente modificarla) o detenerla?
No tengo conocimiento sobre cómo se propagan las suposiciones del compilador en ese caso.
Supongo que los supuestos de no constancia para que se pase como no constante b
Debería ser suficiente y permitir las modificaciones, pero es una suposición.
La mayoría de las respuestas fueron sobre ser capaz Modificar a
o b
, o llamar a métodos no constantes.Sé que si paso el mismo objeto a ambos const
y non-const
Yo puedo hacer eso.Mi duda radica más en si voy a abandonar el programa cuando la función regrese y si puede romper algunas suposiciones del compilador, por ejemplo:
class A(){
int value;
}
void function1(const A & arg1);
void function2(A & arg1);
void function3(const A & arg1, A & arg2);
A a;
a.value=5;
function1(a);
if(a.value==5){/*...*/;} // the if can be optimized out to true, because [a] was const
a.value=5;
function2(a);
if(a.value==5){/*...*/;} //must be checked, [a] could have been modified
a.value=5;
function3(a, a);
if(a.value==5){/*...*/;} // ???
La pregunta más similar que he encontrado (pero en realidad no es así)
Modificar uno mismo dentro del método constante mediante un puntero no constante a uno mismo
Solución
El problema con
return_type function(const argument_type & a, argument_type & b);
y una llamada function( o , o )
es que la función probablemente
modifica el objeto a través de un argumento formal
b
, mientrasal mismo tiempo esperando un argumento formal
a
permanecer sin cambios.
Por lo tanto, probablemente romperá los supuestos de la función, lo que resultará, por ejemplo, enresultados incorrectos o un bloqueo.
Hay una función que por diseño A menudo hay este tipo de firma, es decir, el operador de asignación de copia.Su constante argumento formal a
es el argumento proporcionado explícitamente, y su argumento formal mutable (si se le puede llamar así) es el argumento implícito. *this
.Puede comprobar la autorreferencia (alias de los argumentos) o puede copiar e intercambiar.
En resumen, si puede llamar de forma segura a la función con el mismo objeto como argumento a
y como argumento b
Depende de la función, pero es probable que viole los supuestos de la función, que tiene como condición previa implícita que los argumentos formales se refieren a objetos diferentes.
Otros consejos
Tú decides si esa función se puede llamar con el mismo argumento dado dos veces.
De todos modos, no debes intentar determinar si obtienes el mismo objeto dos veces, siempre y cuando la corrección de tu algoritmo no dependa de ello o no hayas dado garantías.
Se pasan exactamente de la misma manera en tiempo de ejecución, la misma referencia/puntero a exactamente lo mismo.
la diferencia con const
ocurre solo en tiempo de compilación.El compilador se asegurará de que usted esté llamando únicamente const
métodos y no intentar modificar las propiedades de este const
objeto, de lo contrario arroja un error de compilación, porque se supone que no debes modificarlo.
Mi conjetura es que los supuestos de no constancia para que se pase como no constante b deberían ser suficientes y permitir las modificaciones, pero es una suposición.
Sí, function
puede llamar no-const
métodos a través de b
pero no a través de a
.
Intuitivamente, esto significa que function
puede cambiar un objeto pasado a través del const
referencia a
si el mismo objeto también se pasa a través del no-const
referencia b
.
En general, const
sólo ofrece garantías sobre lo que puedes o no hacer con un const
variable.Puede haber otras variables que se refieren a la const
variable, o, a objetos dentro de ella, que puedan permitir la const
variable que será modificada por una función que no parece estar modificando una const
variable.
Volviendo a su caso, depende de funciones y clases de un nivel superior al suyo. function
imponer por sí mismos restricciones sobre lo que se puede y lo que no se puede modificar utilizando const
parámetros, funciones miembro, etc.