O que é o uso de referências passageiras const para tipos primitivos?
Pergunta
Em um projeto que manter, eu vejo um monte de código como este para métodos simples get
/ set
const int & MyClass::getFoo() { return m_foo; }
void MyClass::setFoo(const int & foo) { m_foo = foo; }
O que é o ponto em fazer isso em vez do seguinte?
int MyClass::getFoo() { return m_foo; } // Removed 'const' and '&'
void MyClass::setFoo(const int foo) { m_foo = foo; } // Removed '&'
Passar uma referência a um tipo primitivo deve exigir o mesmo (ou mais) esforço como passar-se o valor do tipo, certo?
É apenas um número depois de tudo ...
existe esta apenas algumas tentativas micro-otimização ou é um verdadeiro benefício?
Solução
A diferença é que se você conseguir esse resultado em uma referência a si mesmo você pode acompanhar as mudanças da variável de membro inteiro em seu próprio nome variável sem recuperar a função.
const &int x = myObject.getFoo();
cout<<x<<endl;
//...
cout<<x<<endl;//x might have changed
Provavelmente não é a melhor escolha de design, e é muito perigoso para retornar uma referência (const ou não), no caso de uma variável que será libertado de escopo é retornado. Então, se você retornar uma referência, tenha cuidado para ter certeza que não é uma variável que sai do escopo.
Há uma ligeira diferença para o modificador também, mas novamente provavelmente não algo que vale a pena fazer ou que se pretendia.
void test1(int x)
{
cout<<x<<endl;//prints 1
}
void test2(const int &x)
{
cout<<x<<endl;//prints 1 or something else possibly, another thread could have changed x
}
int main(int argc, char**argv)
{
int x = 1;
test1(x);
//...
test2(x);
return 0;
}
Assim, o resultado final é que você obter alterações, mesmo após os parâmetros são passados.
Outras dicas
Para mim, a passagem de um referência const para primitivas é um erro. Ou você precisa para modificar o valor e, nesse caso você passar um referência não-const , ou você só precisa acessar o valor e, nesse caso você passar um const .
referências Const deve ser usado apenas para as classes complexas, quando os objetos copiando poderia ser um problema de desempenho. No caso de primitivas, a menos que você precise modificar o valor da variável que você não deve passar uma referência . A razão é que referências ter mais tempo de computação do que não-referências , uma vez que com referências , o programa precisa para olhar para cima em uma tabela para encontrar o endereço do objeto. Quando este tempo look-up é mais curto do que o tempo de copiar, as referências são uma melhoria.
Geralmente, ints e endereços tem o mesmo comprimento byte em implementações de baixo nível. Assim, o tempo de copiar um int como um valor de retorno para uma função é equivalente ao tempo de copiar um endereço . Mas, no caso em que um int é devolvido, sem olhar para cima é realizada, portanto, o desempenho é aumentado.
A principal diferença entre retornar um valor e retornando uma referência const é que você pode, então, const_cast essa referência e alterar o valor.
É um exemplo de má concepção e uma tentativa de criar um design inteligente, onde fácil e concisa projeto seria mais do que suficiente. Em vez de apenas retornar um valor o autor faz leitores de código acho que intenção ele poderia ter tido.
Não há muito benefício. Eu já vi isso em quadro ou macro getters gerados e setters antes. O código de macro não fez distinção entre os tipos primitivos e não-POD e const type&
apenas utilizado em toda a linha para setters. Eu duvido que é uma questão de eficiência ou um mal-entendido genuíno; as possibilidades são esta é uma questão de consistência.
Eu acho que este tipo de código é escrito que não entenderam o conceito de referências e usá-lo para tudo, incluindo tipos de dados primitivos. Eu também vi algum código como este e não pode ver qualquer vantagem de fazer isso.
Não há nenhum ponto e benefício, exceto
void MyClass::setFoo(const int foo)
void MyClass::setFoo(const int& foo)
como então você não será capaz de reutilizar 'foo' dentro 'setFoo' implementação variável. E eu acredito que 'int &' é só porque Guy apenas se acostumar a passar todas as coisas por referência const e não há nada de errado com isso.