c++ - friend class function
ampersand(&) al final de la variable, etc. (5)
Soy un noob de C ++ y tengo un problema para comprender la sintaxis de c ++ en un código. Ahora estoy bastante confundido.
class date
{
private:
int day, month, year;
int correct_date( void );
public:
void set_date( int d, int m, int y );
void actual( void );
void print( void );
void inc( void );
friend int date_ok( const date& );
};
Con respecto al carácter ''&'', entiendo su uso general como referencia, dirección y operador lógico ...
por ejemplo int * Y = & X
¿Cuál es el significado de un operador & al final del parámetro?
friend int date_ok( const date& );
Gracias
editar:
Gracias por las respuestas. Si entendí esto correctamente, el nombre de la variable simplemente se omitió porque es solo un prototipo. Para el prototipo no necesito el nombre de la variable, es opcional. ¿Es eso correcto?
Sin embargo, para la definición de la función definitivamente necesito el nombre de la variable, ¿verdad?
El uso de & al final de un tipo en un prototipo de función permite pasar por referencia, en lugar de pasar por valor (copia). De esta manera puede modificar el objeto de fecha en la función de amigo.
friend int date_ok( const date& );
Amigo: en su definición de clase, esto significa que está diciendo que una función date_ok
puede acceder a todos los parámetros de su clase. De hecho, significa que es casi un miembro de su clase, así que considere agregar esta función amiga en lugar de una función miembro. (a menos que tenga otras buenas razones, como no contaminar su clase con definiciones extranjeras)
En caso afirmativo, también considere hacer de esa una función estática, podría tener todo el mismo acceso a las entrañas de su clase de objeto de fecha. Pero eso sería más natural.
cf. El libro "101 C ++ codificación estándar". Prefiere definir funciones miembro estáticas, favorece el acoplamiento suelto.
En este contexto, &
no es un operador. Es parte del tipo.
Para cualquier tipo T
dado, el tipo T&
es una "referencia a T
".
El símbolo &
de hecho, tiene tres significados en C ++ , y es importante reconocer esos significados diferentes.
- "dirección de" cuando se aplica a una expresión
- "referencia" cuando parte de un tipo
- "Y a nivel de bit" cuando se aplica a dos números
De manera similar, *
tiene al menos tres significados, y una vez que los hayas comprendido, tendrás punteros y referencias hacia abajo. :-)
Si he entendido esto correctamente, el nombre de la variable simplemente se omitió allí porque es solo el prototipo. Y para el prototipo no necesito el nombre de la variable, es opcional. ¿Es eso correcto?
Sí.
Sin embargo, para la definición de la función necesito definitivamente el nombre de la variable, ¿verdad?
No. Aunque normalmente lo querrás (¡de lo contrario, ¿cuál es el punto?) Hay algunas circunstancias en las que no lo haces, normalmente cuando solo has introducido el parámetro para participar en trucos relacionados con la sobrecarga.
Pero hablando puramente técnicamente, puede omitir el nombre del argumento de la declaración y / o la definición que desee.
Entonces, para empezar, creo que podría estar más confundido ya que el autor de ese código omitió algo bastante importante (aunque opcional): el nombre de la variable.
Vamos a reescribir eso:
friend int date_ok( const date& check);
El tipo de la variable ''check'' es const date&
. Lo estamos pasando a la función como una ''referencia constante''. En otras palabras, es un alias de lo que pasamos (a través de la magia del puntero), pero no podemos modificarlo.
La razón por la que hacemos esto es para que podamos pasar objetos grandes (como un std::vector
) a funciones sin hacer una copia de ellos. Pasar por valor incurre en una operación de copia. Para un int, eso no importa (lleva casi nada de tiempo), para una clase, podría ser más significativo. La regla de oro es siempre pasar objetos por referencia y pasarlos por referencia constante si no tiene la intención de modificarlos. (Esta regla de oro ignora la semántica de movimientos, pero supongo que todavía no lo sabe).
Gracias por las respuestas. Si he entendido esto correctamente, el nombre de la variable simplemente se omitió allí porque es solo el prototipo. Y para el prototipo no necesito el nombre de la variable, es opcional. ¿Es eso correcto?
Sin embargo, para la definición de la función necesito definitivamente el nombre de la variable, ¿verdad?
const date&
siendo aceptado por el método date_ok
significa que date_ok
toma una referencia de tipo const date
. Funciona de forma similar a los punteros, excepto que la sintaxis es ligeramente más ... azucarada
en su ejemplo, int* Y = &x
hace que Y
sea un puntero de tipo int
. y luego le asigna la dirección de x
. Y cuando me gustaría cambiar el valor de "cualquiera que sea la dirección señalada por Y
", digo *Y = 200;
asi que,
int x = 300;
int *Y = &x;
*Y = 200; // now x = 200
cout << x; // prints 200
En su lugar ahora uso una referencia
int x = 300;
int& Y = x;
Y = 200; // now x = 200
cout << x; // prints 200