c++ - usar - Variables estáticas en funciones miembro
variable static java (5)
¿Puede alguien explicar cómo funcionan las variables estáticas en las funciones miembro en C ++?
Dada la siguiente clase:
class A {
void foo() {
static int i;
i++;
}
}
Si declaro varias instancias de A
, ¿llamar a foo()
en una instancia incrementa la variable estática i
en todas las instancias? ¿O solo en el que fue llamado?
Supuse que cada instancia tendría su propia copia de i
, pero al pasar por algún código que tengo parece indicar lo contrario.
Gracias por el buen ejemplo! ¿Habría alguna forma de lograr algo que haga que el alcance de static sea específico para la instancia, de modo que, por ejemplo, o1.foo (); // i = 1 y $ o2.foo (); // i> = 1 ...? - Stingery
Creo que una de las únicas formas debe ser hacer una variable miembro de clase bool y luego condicionar la inicialización a su valor y solo cambiar su valor al hacer la inicialización. Puedo imaginar una forma potencialmente más sofisticada donde una variable de mapa estática tiene la instancia como clave, pero eso parece un poco complicado.
Como la class A
es una class A
no es de plantilla y A::foo()
es una función que no es de plantilla. Solo habrá una copia de static int i
dentro del programa.
Cualquier instancia de A
objeto A
afectará el mismo i
y la duración de la vida permanecerá en el programa. Para agregar un ejemplo:
A o1, o2, o3;
o1.foo(); // i = 1
o2.foo(); // i = 2
o3.foo(); // i = 3
o1.foo(); // i = 4
Desafortunadamente, static
palabra clave static
tiene algunos significados diferentes no relacionados en C ++
Cuando se usa para miembros de datos, significa que los datos se asignan en la clase y no en instancias.
Cuando se usa para datos dentro de una función, significa que los datos se asignan estáticamente, se inicializan la primera vez que se ingresa el bloque y dura hasta que el programa se cierra. Además, la variable solo es visible dentro de la función. Esta característica especial de la estática local a menudo se usa para implementar la construcción diferida de singletons.
Cuando se usa en un nivel de unidad de compilación (módulo) significa que la variable es como global (es decir, asignada e inicializada antes de que se ejecute
main
y se destruya después de las salidasmain
) pero que la variable no estará accesible o visible en otras unidades de compilación .
Agregué un poco de énfasis en la parte que es más importante para cada uso. El uso (3) se desaconseja un tanto a favor de los espacios de nombre sin nombre que también permite declaraciones de clase no exportadas.
En su código, la palabra clave static
se usa con el significado del número 2 y no tiene nada que ver con las clases o instancias ... es una variable de la función y solo habrá una copia de la misma.
Como bien dijo iammilind , sin embargo, pudo haber múltiples instancias de esa variable si la función era una función de plantilla (porque en ese caso la función misma puede estar presente en muchas copias diferentes en el programa). Incluso en ese caso, las clases y las instancias del curso son irrelevantes ... ver el siguiente ejemplo:
#include <stdio.h>
template<int num>
void bar()
{
static int baz;
printf("bar<%i>::baz = %i/n", num, baz++);
}
int main()
{
bar<1>(); // Output will be 0
bar<2>(); // Output will be 0
bar<3>(); // Output will be 0
bar<1>(); // Output will be 1
bar<2>(); // Output will be 1
bar<3>(); // Output will be 1
bar<1>(); // Output will be 2
bar<2>(); // Output will be 2
bar<3>(); // Output will be 2
return 0;
}
Respuesta simplificada: las variables estáticas, independientemente de si son miembros de una clase (sin plantilla) o una función (sin plantilla), se comportan, técnicamente, como una etiqueta global cuyo alcance está limitado a la clase o función.
Una vez dejé un const char * que era un local estático (en una función miembro) apuntando a otra cadena de estilo c que en realidad era un miembro de instancia de la clase. El destructor del objeto liberó la memoria del puntero de instancia en este caso particular, y la siguiente instancia de la clase tenía un valor no deseado porque el tiempo de ejecución consideraba el local estático como inicializado, aunque se dejaba apuntando donde no debería.
Los locales estáticos son más fáciles de manejar dentro de funciones globales o funciones estáticas de miembros.
El comportamiento de la plantilla fue cubierto arriba. ¿Qué tal la seguridad de los hilos (o, si no me equivoco, la falta de ellos)?