Referências em C++

Jinku Hu 12 outubro 2023
  1. Use a notação & attr(optional) declarator para declarar uma referência lvalue em C++
  2. Use referências para implementar protótipos de função em C++
Referências em C++

Este artigo demonstra os vários métodos de como usar referências em C++.

Use a notação & attr(optional) declarator para declarar uma referência lvalue em C++

As referências definem nomes alternativos para objetos. Eles não são objetos em si e, conseqüentemente, não podemos ter matrizes de referências ou ponteiros para referências. As referências referem-se apenas a objetos já existentes e são vinculadas a esses objetos, o que significa que nenhuma modificação é permitida após a declaração.

Além disso, as referências devem ser inicializadas e, quando a operação é conduzida usando os nomes de referência, os objetos vinculados são modificados. Observe que o último recurso os torna bastante semelhantes aos ponteiros. Podemos considerar as referências como alternativas aos ponteiros, exceto que o primeiro pode ser usado como nomes de variáveis ​​regulares sem uma notação de desreferência para acessar o valor do objeto correspondente. Se quisermos imitar o comportamento das referências, podemos declarar um ponteiro const para o tipo fornecido. Este último é caracterizado com as mesmas características das referências, exceto pela notação de acesso aos valores.

No código de exemplo a seguir, a variável xr é declarada como a referência a um x, representando um objeto int. Uma vez que xr é inicializado durante a declaração, ele não pode ser reatribuído para se referir a um objeto diferente de qualquer tipo. Por outro lado, podemos definir nomes de alias diferentes, como xr, para o mesmo objeto ao qual se refere. A saber, xrc é uma referência qualificada const, o que significa que o valor do objeto correspondente só pode ser acessado e não pode ser modificado usando o nome alternativo.

#include <iostream>

using std::cout;
using std::endl;

int main() {
  int x = 5;
  int& xr = x;
  const int& xrc = x;

  xr *= xr;
  //    xrc *= x; Error
  cout << "xr: " << xr << endl;
  cout << "xrc: " << xrc << endl;

  return EXIT_SUCCESS;
}

Resultado:

xr : 25 xrc : 25

Podemos declarar várias referências ao mesmo objeto, conforme demonstrado no fragmento de código a seguir. Ainda assim, deve-se estar ciente de que as modificações de qualquer um dos aliases afetarão o mesmo objeto.

#include <iostream>

using std::cout;
using std::endl;

int main() {
  int x = 5;
  int& xr = x;
  int& xrr = x;

  xr *= xr;
  xrr *= xrr;
  cout << "xr: " << xr << endl;
  cout << "xrr: " << xrr << endl;

  return EXIT_SUCCESS;
}

Resultado:

xr : 625 xrr : 625

Use referências para implementar protótipos de função em C++

As referências são utilizadas principalmente para fornecer interfaces de função mais limpas, mas também porque a linguagem C++ fornece recursos de sobrecarga de operador e a notação deve ser a mesma para todos os operadores. O último seria complicado se não houvesse conceitos de referência na linguagem. Assim, usar os operadores que precisam tomar argumentos como ponteiros poderia ser semelhante a ++&x.

Funções que precisam tomar objetos para acessar valores podem especificar os argumentos correspondentes como referências const e se a modificação também for necessária sem const. Por exemplo, a função printVector usa uma referência const para std::vector para imprimir os elementos para o fluxo cout, mas swapElements precisa trocar cada elemento, então precisamos ter uma referência regular para o objeto.

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>

using std::cout;
using std::endl;
using std::setw;
using std::string;
using std::vector;

template <typename T>
void printVector(const vector<T> &vec) {
  for (auto &i : vec) {
    cout << i << "; ";
  }
  cout << endl;
}

template <typename T>
void swapElements(vector<T> &vec) {
  for (auto iter = vec.begin(); iter < vec.end() - 1; ++iter) {
    std::swap(*iter, *(iter + 1));
  }
}

int main() {
  vector<int> vec1 = {43, 5, 123, 94, 359, -23, 2, -1};

  printVector(vec1);
  swapElements(vec1);
  printVector(vec1);

  return EXIT_SUCCESS;
}

Resultado:

43;
5;
123;
94;
359;
- 23;
2;
- 1;
5;
123;
94;
359;
- 23;
2;
- 1;
43

Observe que todos os exemplos anteriores de referências, incluindo os const, são chamados de referências de lvalue. Essas referências são usadas para se referir aos objetos que precisam preservar os valores válidos depois de acessá-los ou modificá-los. A linguagem C++ também fornece referências rvalue, que são utilizadas para se referir aos objetos temporários.

Um objeto temporário é uma suposição para o programador de que o objeto fornecido não será usado novamente. As referências de rvalue são especificadas usando a notação && attr(optional) declarator e os objetos são acessados ​​como as referências de lvalue. As referências Rvalue são utilizadas para implementar operações eficientes, como mover o construtor e mover a atribuição para evitar cópias caras de objetos grandes.

Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook