2010-08-05 14 views
5

Esta es una expansión del alcance de previous question of mine.¿Qué significa exactamente "estático" cuando se declaran variables "globales" en C++?

¿Qué es exactamente "estático", cómo se usa y cuál es el propósito de usar "estático" cuando se trata de C++?

Gracias.

+2

Pero "la pregunta anterior" se trata de Java ... – kennytm

+4

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

+0

@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

Respuesta

10

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.

+1

En su segundo fragmento de código, ¿no quiso usted precisamente eliminar el uso de 'static'? –

13

Significa que la variable es local en una unidad de traducción (simplemente, en un único archivo fuente) y no se puede acceder desde fuera de ella. Este uso de la estática es, de hecho, en desuso en la corriente C++ estándar - en lugar que se supone que usar espacios de nombres anónimos:

static int x = 0;  

debería ser:

namespace { 
    int x = 0;  
} 
+0

1. ¿Qué es una unidad de traducción? 2. ¿Cómo funciona esta idea cuando se trata de clases? – Hristo

+2

El espacio anónimo de nombres realmente necesita ser golpeado en la cabeza de las personas. Hay demasiados programadores de C++ que aprendieron C++ hace 15 años y no se han molestado en aprender nada desde entonces. –

+0

@Hristo Las clases no pueden ser estáticas, pero las instancias pueden serlo. –

2

estático básicamente significa que una variable está ligada a la vida útil del programa y no de una función o instancia de clase determinada. ¿Cuándo deberías usarlo? No lo hagas ¿Cuál es el propósito? Depuración de datos, en su mayoría.

Generalmente, en C++, si se encuentra usando datos estáticos, lo ha hecho mal. Hay momentos en los que es apropiado, pero son muy raros.

+0

.. jaja :) No use estática. Lo suficientemente fácil de recordar. ¿Qué tienes que decir sobre la respuesta de Neil? Además, ¿su consejo es válido para C también? – Hristo

+0

@Hristo: Sí. Además, la respuesta de Neil no está mal. Para su propósito, la estática ha sido reemplazada. Eso no significa que sirvió un propósito útil para empezar. Es el tipo de cosa donde, hay algunas cosas que son bastante imposibles sin estática. Sin embargo, puede ser muy usado por los nuevos programadores y debe evitarse siempre que sea posible, y aquellas cosas para las cuales es realmente necesario son bastante raras. – Puppy

+0

Gracias por la aclaración. – Hristo

6

Esto parece estar bastante bien cubierto here.

Pero parafraseando, hay 2 usos en C

  1. impide la utilización de una variable global fuera del ámbito del archivo que lo define.
  2. Permitir variables locales dentro de una función de persistir al otro lado de invocaciones de la función, como en

    int getNextId() { int estática id = 0; return id ++; }

C++ hereda ambos, y añade dos usos propios.

  1. variables miembro estáticas: Variables que son "compartidas" entre todas las instancias de una clase, y también pueden ser accesos sin referencia a una instancia de la clase. Compartido parece una palabra incorrecta, pero en esencia creo que el resultado es que cualquier referencia a una variable miembro estática hace referencia a la misma ubicación de memoria.
  2. métodos estáticos: métodos que pueden invocarse sin referencia a una instancia específica de la clase que lo define.
+0

¡Respuesta agradablemente estructurada! Gracias por la respuesta y la referencia. Parece de su respuesta que "estático" en C++ no es muy diferente de Java. – Hristo

+1

@Hristo: Java solo tiene los dos últimos casos. Los primeros casos de uso 1 y 2 (la parte C) no se pueden usar allí. –

+0

@David ... oh ok. Gracias. Por cierto ... Leeré tu respuesta oficial cuando tenga un poco más de tiempo para dedicar la cantidad adecuada de enfoque. ¡Gracias por tomarse el tiempo! – Hristo

0

Los miembros de la clase estática son datos y funciones que están asociados con la clase en sí, en lugar de con los objetos de la clase.

En el siguiente ejemplo, la clase Fred tiene un miembro de datos estáticos x_ y un miembro de datos de instancia y_. Solo hay una copia de Fred :: x_, independientemente de cuántos objetos Fred se creen (incluidos los objetos Fred), pero hay un y_ por objeto Fred. Por lo tanto, se dice que x_ está asociado con la clase y se dice que y_ está asociado con un objeto individual de la clase. Del mismo modo, la clase Fred tiene una función de miembro estática f() y una función de miembro de instancia g().

class Fred { 
    public: 
     static void f() throw();       <-- 1 
     void g() throw();         <-- 2 
    protected: 
     static int x_;          <-- 3 
     int y_;           <-- 4 
}; 

(1) función miembro asociada con la clase

(2) función miembro asociada con un objeto individual de la clase

(3) miembro de datos asociados con la clase

(4) Miembro de datos asociado con un objeto individual de la clase

Uso:

Cuando desee mantener el número de instancias de una clase creada, utilice la variable estática. Por ejemplo, en una clase 'Coche' cada instancia de Coche puede tener un número de serie único (_y en este caso) y la compañía puede querer realizar un seguimiento del número de automóviles producidos (_x en este caso).

+0

¡Respuesta agradablemente estructurada! Gracias por la respuesta y la referencia. Parece de su respuesta que "estático" en C++ no es muy diferente de Java. – Hristo

+0

Aunque esto realmente no responde a la pregunta original ... Esto solo explica la estática en el contexto de las clases. No es el alcance global. Para el alcance global, se trata exactamente igual que C. –

1

Cuando estática se usa en una clase en C++, significa más o menos lo mismo que en Java. Para las variables, significa que existe una sola instancia de la variable para todas las clases y para las funciones, esto significa que la función no tiene acceso implícito a este puntero en absoluto.

En C y C++ cuando estático se usa para una variable o función global, significa que la variable solo se puede hacer referencia en el archivo C o C++ actual. En otras palabras, el compilador no debe generar símbolos de reubicación para la variable o función.

Cuando estática se usa al lado de una variable en una función local, significa que la variable no se sale del alcance, sino que conservará su valor de función-llamada a función-llamada. La variable se convierte efectivamente en una variable global a la que solo se puede acceder desde la función dada.

Cuestiones relacionadas