2012-07-24 29 views
26

que tengo un espacio de nombres foo que contiene un entero bar, declarado así que ...estática vs variables no estáticas en espacio de nombres

foo.h:

namespace foo { 
    int bar; 
} 

Ahora si incluyo foo.h en una sola archivo, esto funciona bien. Pero surge un problema cuando incluyo foo.h desde dos o más archivos: obtengo un error de enlazador. Descubrí que si declaro bar como static, puedo incluir foo.h en más de un archivo. Esto me parece extraño, porque no sabía que se podía declarar una variable estática dentro de un espacio de nombres. (¿Qué significa eso incluso?)

¿Por qué funciona esto? Y más importante, ¿por qué no funciona sinstatic? ¿Qué significa static cuando se usa en un namespace?

+0

Votación. Fue exactamente mi problema y lo resolvió :) –

Respuesta

26

Existen varios significados para static en diferentes contextos. En este contexto particular, significa que la variable tiene un enlace interno y, por lo tanto, cada unidad de traducción que incluye ese encabezado tendrá su propia copia de la variable.

Tenga en cuenta que si bien esto silenciará el error del enlazador, lo hará manteniendo una variable foo::bar por separado para cada uno de los archivos de objeto generados (los cambios no serán visibles en los diferentes archivos de objeto).

Si desea una sola variable, debe declararla como extern en el encabezado y proporcionar una definición única en una unidad de traducción.

19

Cuando declara una variable como static, significa que su alcance está limitado a la unidad de traducción dada solamente. Sin static el alcance es global.

Cuando se declara una variable como static dentro de un archivo .h (dentro o fuera de namespace; no importa), e incluir el archivo de cabecera en varios archivos .cpp, se convierte en la variable static con ámbito local de cada uno de los .cpp archivos.
Así que ahora, cada archivo .cpp que incluye ese encabezado tendrá su propia copia de esa variable.

Sin la palabra clave static, el compilador generará una sola copia de esa variable, por lo que tan pronto como incluya el archivo de encabezado en múltiples archivos .cpp, el vinculador se quejará de las definiciones múltiples.

3

El problema se debe a que tiene más de una definición de la variable. Las definiciones en diferentes unidades de traducción entran en conflicto entre sí, al igual que las múltiples definiciones de funciones no en línea no funcionarían.

Cuando se hace la variable estática, se proporciona el enlace interno variable, por lo que cada unidad de traducción tiene su propia copia independiente.

Lo que probablemente realmente desee es poner solo la declaración en un encabezado (usando extern) y luego poner la definición en un archivo de implementación.

Cuestiones relacionadas