FAQ Lite
Referências

[ 8.1 ] O que é uma referência?
[ 8.2 ] O que acontece se você atribui valor (assign) a uma referência?
[ 8.3 ] O que acontece se você retorna uma referência?
[ 8.4 ] Como você pode limpar (reset) uma referência e fazê-la referenciar a um outro objeto?
[ 8.5 ] Quando eu devo usar referências, e quando eu devo usar pointers?

[ 8.1 ]   O que é uma referência?

Um alias (um nome alternativo) para um objeto.

Referências são usadas freqüentemente para passar-parâmetros-por-referência:

    void swap(int& i, int& j)
    {
      int tmp = i;
      i = j;
      j = tmp;
    }
    
    main()
    {
      int x, y;
      // ...
      swap(x,y);
    } 
Aqui i e j são usados como alias para os objetos x e y, respectivamente. Em outras palavras, i é x, não é um pointer para x, não é uma cópia de x, mas é o próprio x. Tudo o que você fizer com i será feito com x, e vice versa.

Ok. Isso é o que você deveria pensar sobre referências como um programador. Agora, correndo o risco de confundí-lo por lhe dar uma perspectiva diferente, aqui está como referências são implementadas. Internamente, uma referência i para o objeto x é tipicamente o endereço de máquina do objeto x. Mas quando o programador especifica i++, o compilador gera o código que incrementa x. Em particular, os bits de endereço que o compilador usa para localizar x não são alterados. Um programador C pensará sobre isso como se você usasse o estilo C passagem-de-parâmetros-por-pointers com a variação sintática de (1) mover o & do chamador para o chamado, e (2) eliminar os *s. Em outras palavras, um programador C pensará em i como uma macro para (*p), onde p é um pointer para x (isto é, o compilador automaticamente diferencia o pointer, i++ é alterado para (*p)++; i = 7 é automaticamente alterado para *p = 7)

Nota importante: Mesmo sabendo que uma referência é freqüentemente implementada em linguagem assembler usando um endereço, não pense em referência como uma maneira diferente de se ver o pointer para um objeto. Uma referência é o objeto. Ela não é um pointer para o objeto, nem uma cópia do objeto. É o próprio objeto.

Topo
[ 8.2 ] O que acontece se você atribui valor (assign) a uma referência?

Você altera o referente (o objeto ao qual a referência se refere).

Lembre-se: a referência é o referente, então, alterando-se a referência altera-se o referente. Em liguagem de autores de compiladores, uma referência é um "lvalue" (algo que pode aparecer do lado esquerdo de um operator).

Topo
[ 8.3 ] O que acontece se você retorna uma referência?

A chamada a uma função pode aparecer do lado esquerdo de uma atribuição operator.

Essa habilidade pode parecer estranha em um primeiro momento. Por exemplo, ninguém pensa que a expressão f() = 7 faz sentido. Mais ainda, se a é um objeto de class Array, muitas pessoas pensam que a(i) = 7 faz sentido, ainda que a[i] seja, na realidade, uma chamada de função de modo disfarçado (Já que chama Array::operator[](int), que é o operator subscrito para class Array).

    class Array {
    public:
      int size() const;
      float& operator[] (int index);
      // ...
    };
    
    main()
    {
      Array a;
      for (int i = 0; i < a.size(); ++i)
        a[i] = 7;    // This line invokes Array::operator[](int)
    } 
Topo
[ 8.4 ]  Como você pode limpar (reset) uma referência e fazê-la referenciar a um outro objeto?

Não há como se fazer isso.

Você não pode separar a referência do referente.

Diferentemente de um pointer, uma vez que a referência está associada a um objeto, não se pode mais reassocia-la a um outro objeto. A referência, por si mesmo, não é um objeto. (Ela não tem uma identificação; tomando o endereço de uma referência, obtém-se o endereço do referente; lembre-se a referência é o referente.

Nesse sentido, a referência é semelhante a um pointer const, tal como int* const p (contrariamente a pointer para uma const, como const int* p). Apesar da semelhança superficial, não confunda referências com pointers, referências e pointers não são a mesma coisa.

Topo
[ 8.5 ]  Quando eu devo usar referências, e quando eu devo usar pointers?

Use referências onde for possível, e pointer onde você for obrigado.

Referências são usualmente preferíveis aos pointers porque em nenhum momento você precisa reassociá-las a objetos. Isso significa que referências são mais úteis na definição das interfaces public de classes. Referências geralmente aparecem na superfície de um objeto, e pointers em seu interior.

A exceção ao que se definiu acima é quando o parâmetro de uma função, ou um valor de retorno, necessita de um valor de alerta. Isso é melhor conseguido retornando/passando um pointer, e dando ao valor null do pointer o significado de valor de "alerta" (referências devem sempre estar associadas a objetos,  não a um pointer null).

Nota: Velhos programadores C algumas vezes não gostam de referências, já que elas implicam em semântica que não é explícita no código chamador. Após alguma experiência com C++, entretanto, rapidamente se percebe que essa é uma forma de ocultar informação, o que é uma vantagem, mais do que uma limitação. Ou seja, programadores devem escrever código nos termos do problema a ser resolvido, mais do que nas características da máquina onde o programa será executado.

Topo Anterior Próximo Índice
C++ FAQ Lite
Copyright © 1991-98 by Marshall Cline Ph.D., cline@parashift.com
Tradução: Dagoberto Haele Arnaut

| Home | Bookmarks | Universidades | Para Saber mais | Universidades | WEB Directory | Mapa do site |