2

He leído en el curso de Openclassrooms sobre el polimorfismo en C++ que no se puede crear array de referencias, solo de punteros. Dicen que este es prohibido porque referencias son "etiquetas"...

¿Pueden explicarme más concretamente pero con ejemplos simples el motivo ?

UselesssCat
  • 3,127
  • 1
  • 18
  • 43
Revolucion for Monica
  • 4,154
  • 4
  • 28
  • 80
  • 2
    Esta pregunta es interesante, no veo por que cerrarla. Hay buenas discusiones en [esta pregunta](http://stackoverflow.com/questions/1164266/why-are-arrays-of-references-illegal). Bueno, me atrevería a responder, pero hace tiempo que no veo nada de c++ :P – UselesssCat Apr 25 '17 at 00:41

2 Answers2

2

no se puede crear array de referencias, solo de punteros.

Eso es cierto, pero puedes hacer trampas con la envoltura de referencia que ofrece std::reference_wrapper:

int a = 0, b = 1, c = 2, d = 3, e = 4, f = 5;
std::array<std::reference_wrapper<int>, 6> array {{ a, b, c, d, e, f }};

// Este bucle muestra 0 1 2 3 4 5
for (const auto &valor : array)
    std::cout << valor << ' ';
std::cout << '\n';

a = 1000;
f = 2000;

// Este bucle muestra 1000 1 2 3 4 2000
for (const auto &valor : array)
    std::cout << valor << ' ';
std::cout << '\n';

Como puedes ver en el código de ejemplo (que puedes probar en Wandbox 三へ( へ՞ਊ ՞)へ ハッハッ) hemos modificado las variables a y f que estaban guardadas como referencia en el std::array1 llamado array. Pero esto nos desvía de la pregunta original:

¿Pueden explicarme más concretamente pero con ejemplos simples el motivo?

Para responder adecuadamente a esta pregunta debemos conocer las diferencias entre puntero y referencia en C++, las diferencias más relevantes para este tema concreto son:

  • Un puntero (no constante) es re-asignable (puede apuntar a otros datos después de ser inicializado) mientras que una referencia no (una referencia siempre apunta al mismo dato).
  • Los punteros permiten operar aritméticamente sobre ellos para modificar el lugar al que apuntan, las operaciones aritméticas sobre referencias modifican el dato referenciado, no al lugar al que la referencia apunta.
  • La aritmética de punteros es una característica vital para el funcionamiento de los arreglos, dado que las referencias no tienen aritmética propia no pueden usarse en arreglos.

Pero la respuesta es mucho más sencilla que los tres puntos anteriores, no se puede crear un arreglo de referencias porque el estándar de C++ lo prohíbe (traducción y resaltado míos):

8.3.4 Arreglos

  1. En una declaración T D en que D tiene la forma

    D1 [ expresión-constanteopcional ] secuencia-especificación-atributoopcional

    y el tipo del identificador en la declaración T D1 es "declarador-tipo-lista T", entonces el tipo del identificador de D es arreglo; si el tipo del identificador de D contiene el especificador-de-tipo auto, el programa estará mal formado. T recibe el nombre de tipo del elemento del arreglo; este tipo no debe ser un tipo referencia, [...]

Es muy posible que esta prohibición explícita exista porque de no ser así, los arreglos de referencias necesitarían tener un comportamiento diferente a los arreglos de otros tipos de datos (por las diferencias descritas entre puntero y referencia) causando esto una inconsistencia en el lenguaje.


1No es necesario usar std::array, consigues el mismo resultado con un arreglo de tamaño estático: std::reference_wrapper<int> array[] { a, b, c, d, e, f };.

PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82
1

Hay una pregunta idéntica en stackoverflow: https://stackoverflow.com/a/1164306/4743711

y la respuesta que ponen citando al estándar C++ es:

There shall be no references to references, no arrays of references, and no pointers to references

Que traduciendo (y corrigiendo el número de parágrafo), viene a ser:

Estándar C++ 8.3.2/5

No habrá referencias de referencias, ni arrays de referencias, ni punteros a referencias.

Ese es el motivo, no habla de etiquetas.