Además de todas las discusiones comunes sobre cuándo y cómo pasar posiblemente por referencias para tipos no primitivos, las matrices son bastante especiales aquí.
Debido a la compatibilidad con C, y debido a su problema específico: las matrices pueden ser enormes, las matrices nunca pasan realmente el valor en C ni en C++. La matriz descomposición en un puntero al primer elemento, por lo que cuando se escribe:
void foo(type array[100]);
el compilador está procesando realmente:
void foo(type *array);
Independientemente de cuál sea el tamaño de la matriz es (dos Errores comunes allí: confiando en que array
es una matriz dentro de foo
y en la creencia de que se garantizará que sean 100 elementos en ella.
Ahora, en C++ puede pasar las matrices por referencia E, pero la referencia debe ser del tipo concreto de la matriz, que incluye el tamaño:
void foo_array(type (&array)[100]);
La sintaxis divertido no está diciendo al compilador que la función se llevará a una serie de exactamente 100 elementos de tipo type
. La ventaja no es que el compilador puede realizar tamaño comprobación de que:
// assuming 'type' is defined
int main() {
type array0[99];
type array1[100];
foo(array0); // compiles, but if size=100 is assumed it will probably break
// equivalent to: foo(&array0[0])
// foo2(array0); // will not compile, size is not 100
foo2(array1); // compiles, size is guaranteed to be 100
}
Ahora, el problema es que su función sólo funcionará para una serie de exactamente 100 elementos, y en algunos casos, es posible que desee realizar la misma operación en diferentes tamaños de matriz. Las dos soluciones son: plantilla la función en el tamaño de la matriz que proporcionará una implementación de tamaño seguro para cada tamaño utilizado - mayor tiempo de compilación y tamaño binario, la plantilla se compila para cada tamaño diferente-- o utilizando el pase la sintaxis de valor por valor, que hará que la matriz decaiga, no es segura en tamaño, debe pasar como argumento adicional, menor tiempo de compilación y tamaño binario. Una tercera opción es la combinación de ambos:
void foo(type *array, int size);
template <size_t N>
void foo(type (&array)[N]) {
foo(array, N);
}
En este caso, mientras que habrá una plantilla foo
para cada tamaño, el compilador lo más probable es inline la llamada y el código generado sería equivalente a la persona que llama que proporciona la matriz y tamaño No se necesitan cálculos adicionales y tipo de seguridad para matrices reales.
Ahora, el paso por referencia se utiliza muy raramente con las matrices.
Tal vez su maestro significa "pasar por ** la referencia const ** solo debe usarse si no va a cambiar ninguno de los datos dentro de la función ". – Dan
No, no lo hizo. Nos dijo que es una regla práctica usar solo llamadas por referencia si no vas a cambiar nada. Veo ahora de las respuestas a continuación que incluso los maestros no siempre hablan de lo que están hablando. –
Tienes razón. Los maestros no siempre saben de lo que están hablando. Y a veces lo saben, pero accidentalmente se equivocan. O a veces, dicen lo correcto, y los estudiantes los malinterpretan. No descarta la última opción. – jalf