Mesmo objeto como const e não constante, o que devo assumir a se comportar?
-
20-12-2019 - |
Pergunta
Eu tenho uma função da forma
return_type function(const argument_type & a, argument_type & b);
Se o mesmo objeto é passado como a
e b
, posso continuar com a função (assim, potencialmente, modificar ou interromper?
Eu não tenho o conhecimento sobre como o compilador pressupostos propagar no caso.
Meu palpite é que não constness pressupostos para ser repassado como não-const b
deve ser o suficiente e permitir que as modificações, mas é um palpite.
A maioria das respostas foram sobre ser capaz de para modificar a
ou b
, ou chamada não-const métodos.Eu sei que se eu passar o mesmo objeto como const
e non-const
Eu posso fazer isso.A minha dúvida reside mais no estado que eu estou indo para a esquerda o programa quando a função retorna, e se ele pode travar alguns compilador suposições, por exemplo:
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){/*...*/;} // ???
Mais semelhante pergunta que eu encontrei (mas realmente não é)
Modificando eu dentro de const método não via ponteiro const para auto
Solução
O problema com
return_type function(const argument_type & a, argument_type & b);
e uma chamada function( o , o )
é que a função, provavelmente,
modifica o objeto através do argumento formal
b
, enquantoao mesmo tempo, esperando argumento formal
a
manter-se inalterada.
Então você provavelmente vai quebrar os pressupostos da função, resultando na e.g.resultados incorretos ou de um acidente.
Aqui está uma função que por design muitas vezes tem este tipo de assinatura, a saber, a cópia operador de atribuição.Sua constante argumento formal a
é explícita desde argumento, e o seu mutável argumento formal (se é que se pode chamar assim) é o implícito *this
.Ele pode verificar para a auto-referência (aliasing dos argumentos) ou pode copiar e swap.
Em resumo, se você pode seguramente chamar a função com o mesmo objeto como argumento a
e como argumento b
depende da função, mas as chances são de que você irá violar a função de pressupostos, que tem como pré-requisito implícito que os argumentos formais referem-se a diferentes objetos.
Outras dicas
Você decide se de que a função pode ser chamada com o mesmo argumento dado duas vezes.
De qualquer maneira, você não deve tentar determinar se você receber o mesmo objeto duas vezes, enquanto a exatidão de seu algoritmo não dependem dele ou você não deu garantias.
Eles são passados exatamente da mesma forma em tempo de execução, a mesma referência/ponteiro para exatamente a mesma coisa.
A diferença com const
acontece apenas em tempo de compilação.O compilador irá certificar-se de que você está chamando apenas const
métodos e não tentar modificar as propriedades deste const
objeto, caso contrário, ele gera um erro de compilação, porque você não deve modificá-lo.
Meu palpite é que não constness pressupostos para ser repassado como não-const b deve ser suficiente e permitir que as modificações, mas é um palpite.
Sim, function
pode chamar nãoconst
métodos, através b
mas não via a
.
Intuitivamente, isto significa que function
pode alterar um objecto transmitido através de const
referência a
se o mesmo objeto também é transmitido através de não-const
referência b
.
Em geral, const
só faz garantias sobre o que você pode ou não pode fazer com um const
variável.Pode haver outras variáveis que se referem ao const
variável, ou, para objetos, que podem ativar o const
a variável a ser modificada por uma função que não é a o que é a modificação de um const
variável.
Voltando ao seu caso, é até funções e classes em um nível mais alto do que o seu function
para si impor restrições sobre o que pode e não pode ser modificada usando const
parâmetros, funções de membro, etc.