¿Cuál es la diferencia entre una función ordinaria y una función estática "en términos de asignación de memoria único"?
Nada. Una función estática es como una función global, excepto por el alcance.
Incluso para funciones de miembros no estáticos, no se requiere memoria extra. La función de miembro int C::f(int arg1, int arg2)
es solo azúcar sintáctica para algo como int C__f(C* this, int arg1, int arg2)
.
¿Qué sucede si la función miembro contiene algunas variables locales? En ese caso la función "debe" tener una copia separada de esa variable - específica a el objeto invocando la función ...
Hay una copia de las variables locales para cada invocación de la función (a menos que sean static
). Esta es la razón por la recursión posible en C++.
¿Cómo se resuelve este problema en C++?
Las llamadas a funciones se basan en "marcos de pila". Un marco de pila consta de:
- Los argumentos para la función (incluido el implícito
this
si corresponde).
- Cualquier otra variable local que no sea
static
en la función.
- La "dirección de retorno", que le dice al procesador dónde reanudar la ejecución una vez que se realiza la función.
Cada vez que se invoca una función, se crea un marco de pila. Cuando la función es, el marco de pila se destruye. Si se llama a una función recursivamente, cada nivel de recursión obtiene su propio marco de pila. Por ejemplo, si usted tiene
int factorial(int n) {
if (n <= 1)
return 1;
else
return factorial(n - 1) * n;
}
Entonces, cuando usted llame factorial(3)
, un marco de pila se crea de este modo:
------------------------ stack pointer (SP)
n = 3
RA = <in main()>
Cuando se hace la llamada recursiva a factorial(2)
, se añade una trama adicional al parte superior de la pila
------------------------ SP
n = 2
RA = <in factorial()>
------------------------
n = 3
RA = <in main()>
Otra llamada recursiva se hace, a factorial(1)
.
------------------------ SP
n = 1
RA = <in factorial()>
------------------------
n = 2
RA = <in factorial()>
------------------------
n = 3
RA = <in main()>
Este es el caso base para la recursión, y el valor de retorno de 1 se almacena en un registro. La llamada a la función se ha completado, el marco de la pila superior se destruye y la ejecución continúa en la dirección de retorno guardada.
------------------------ SP
n = 2
RA = <in factorial()>
------------------------
n = 3
RA = <in main()>
Ahora, la llamada a factorial(2)
puede calcular su valor de retorno (2), y otro marco de pila puede ser destruido:
------------------------ SP
n = 3
RA = <in main()>
Finalmente, podemos calcular el resultado de la llamada función original (6), y destruir este marco de pila también.
me gustaría corregir mi pregunta: ¿Por "función miembro" en mi segunda pregunta, me refiero a "función miembro estática" – SlowAndSteady