2010-01-29 18 views
11

Digamos que tengo este programa:Las variables estáticas en los métodos de instancia

class Foo { 
public: 
    unsigned int bar() { 
     static unsigned int counter = 0; 
     return counter++; 
    } 
}; 

int main() 
{ 
    Foo a; 
    Foo b; 
} 

(Por supuesto, este ejemplo no tiene sentido desde que había, obviamente, declaro "contador" como un atributo privado, pero es sólo para ilustrar la problema).

Me gustaría saber cómo se comporta C++ en este tipo de situación: ¿la variable "contador" en el método bar() será la misma para cada instancia?

Respuesta

10

Sí, counter se compartirán en todas las instancias de objetos del tipo Foo en su ejecutable. Siempre que esté en un entorno único, funcionará como se espera como contador compartido.

En un entorno multiproceso, tendrá condiciones de carrera interesantes para depurar :).

+0

+1 por mencionar los peligros en un entorno multiproceso. – Omnifarious

+0

Suponiendo que el compilador aún no lo maneje por usted. La definición del lenguaje es que la variable es consistente en todas las llamadas al método. Por lo tanto, es el trabajo del compilador para hacer cumplir esto, por lo que en los lenguajes multi-hilo (la próxima versión de C++) es el trabajo de los compiladores. En esta versión, depende de la integración del compilador con la biblioteca de subprocesos. gcc ya tiene esto cubierto y garantiza que el acceso a la variable estática es seguro en múltiples hilos. –

+0

@Martin York: es decir, las variables estáticas en C++ 0x están garantizadas para ser locales de subprocesos? Qué interesante, y posiblemente sorprenda grandemente a algunas personas. Como un buen contador de instancias de clases estáticas. De repente, estarás contando instancias por hilo en su lugar. No puedo creer que hagan un cambio como ese. ¡¿Estás seguro?! – Omnifarious

2

Por "ser el mismo para cada instancia" quiere decir que habrá una instancia de esta variable compartida en cada instancia de clase, entonces sí, eso es correcto. Todas las instancias de la clase usarán esa misma instancia de variable.

Pero tenga en cuenta que con las variables de clase tiene que tener en cuenta cosas como multi-threading en muchos casos, que es un tema completamente diferente.

1

De El C++ Programming Language (2ª edición), página 200, por Bjarne Stroustrup:

No utilice estática, excepto en el interior [Normal] funciones (§7.1.2) y las clases (§10.2.4).

+4

Las reglas son fantásticas. __BUT__ solo si se usa en el contexto correcto. Un usuario de nieve puede llevar la cita a Hart. Si quieres citar algo así, debes incluir el contexto completo. –

0

sólo tiene que entender dos cosas:

  1. Las variables estáticas se almacenan en el área estática del programa en ejecución (que es el mismo que el de variable global).
  2. El alcance está limitado por las reglas generales de paréntesis. Las variables adicionales estáticas tienen enlaces internos.
+0

La vida no es la vida del programa. Es desde el primer uso (que puede ser nunca) hasta la destrucción (que es el orden inverso de la creación de variables estáticas). La inicialización de la nota Alos es buena ya que es parte de la función, no de la clase. –

+0

@niel ... ¡¡¡mi mal !! No vi que – sud03r

+0

La última oración es sobre variables estáticas del ámbito del espacio de nombres. Las variables estáticas locales (como las de la pregunta) no tienen ningún vínculo. (No hay forma de referirse a variables locales desde diferentes ámbitos. ¿Cómo se referiría a una variable definida en main? 'Main() :: v' no funciona, por ejemplo). –

1

Su ejemplo fue un par de líneas lejos de ser algo que podría compilar y prueba:

#include <iostream> 
using namespace std; 
class Foo { 
public: 
    unsigned int bar() { 
     static unsigned int counter = 0; 
     return counter++; 
    } 
}; 

int main() 
{ 
    Foo a; 
    Foo b; 

    for (int i=0; i < 10; i++) 
     cout<<i<<". "<<a.bar()<<"/"<<b.bar()<<endl; 
} 

La salida tiene el siguiente aspecto:

0. 1/0 
1. 3/2 
2. 5/4 
3. 7/6 
4. 9/8 
5. 11/10 
6. 13/12 
7. 15/14 
8. 17/16 
9. 19/18 

Así que sí, el contador se comparte a través todas las instancias.

+0

Lo que es divertido es que su salida es un ejemplo perfecto de cómo funcionan los puntos de secuencia y el orden de ejecución y puede dar como resultado resultados contradictorios. – Omnifarious

Cuestiones relacionadas