La palabra clave static
tiene diferentes significados en C++, dependiendo del contexto.
Cuando se declara una función libre o una variable global que significa que la función no esté disponible fuera de esta unidad de traducción individual:
// test.cpp
static int a = 1;
static void foo() {}
Si el resultado de la compilación de esa unidad de traducción está vinculado con una diferente la unidad de traducción que contiene los símbolos a
y foo
no romperá la regla de una sola definición, ya que en esta unidad de traducción particular a
y foo
son símbolos privados. Este uso ha sido obsoleto por espacios de nombres sin nombre.
// test2.cpp
namespace {
static int a = 1;
static void foo() {}
}
Cuando se declara una variable local dentro de una función significa que el tiempo de vida de la variable se extenderá desde la primera llamada a la función hasta el final del programa, y no sólo para la duración de la llamada:
int foo() {
static int counter = 0;
return ++counter;
}
int main() {
for (int i = 0; i < 10; ++i) {
std::cout << foo() << std::endl;
}
}
En el código anterior, counter
se inicializa una vez cuando foo
se llama por primera vez, pero la variable sobrevivirán la función y mantener el valor a través de diferentes llamadas a funciones. El código anterior imprimirá "1 2 3 4 ... 10". Si la variable no se declaró static
, entonces la salida sería "1 1 1 ... 1".
Dentro de un alcance de clase, static
significa que el miembro es un miembro de la clase, y no de una instancia particular.Este uso es equivalente al uso en su otra pregunta: el uso de ese miembro en particular no está vinculado a ningún objeto específico.
struct test {
int x;
static int y;
};
int test::y; // need to define it in one translation unit
int main() {
// test::x = 5; // !error cannot access a non-static member variable
// without an instance
test::y = 5; // ok
test t, other;
t.x = 10; // ok
t.y = 15; // ok, the standard allows calling a static member through
// an instance, but this is the same as test::y
}
En este caso, el miembro de x
es un atributo de miembro no estático, y como tal no es una diferente x
para cada instancia de la clase. En el programa de ejemplo t.x
y other.x
, consulte diferentes enteros. Por otro lado, y
es static
y, por lo tanto, hay una sola instancia de test::y
en el programa. Incluso si el estándar permite llamar a t.y
y other.y
, ambos usos se refieren a la misma variable. Lo mismo ocurre con los métodos miembros. Si son estáticos, son métodos de nivel de clase y se pueden invocar sin una instancia, mientras que si no son estáticos se aplican a una instancia concreta y se debe usar la sintaxis a.b
o a->b
.
Este uso de static
es similar al uso de la misma palabra clave en Java, mientras que los otros dos no están presentes en ese idioma. Hay un uso de la palabra clave en Java que no está presente en C++, y es el uso de inicializadores de clases estáticos (un bloque de código en el nivel de clase rodeado por static { ... }
). En Java, ese bloque de código se ejecutará cuando la clase se cargue y solo una vez. La inicialización de variables de miembros estáticos en C++ debe realizarse en el inicializador de la definición de variable.
Pero "la pregunta anterior" se trata de Java ... – kennytm
Depende del uso de estática del que se trate. Una de mis citas favoritas "No es una nueva versión de C++ hasta que encuentren un nuevo uso para static" – JaredPar
@Kenny ... sí, lo sé. Es por eso que quiero ampliar el alcance para considerar C/C++. Obtuve la respuesta con Java y me pregunto si eso difiere cuando se trata de C/C++. – Hristo