2010-05-21 13 views
13
// MyClass.h 

namespace MyNamespace { 

    static const double GasConstant = 1.987; 

    class MyClass 
    { 
    // constructors, methods, etc. 
    }; 
} 

Yo antes tenía GasConstant declarado dentro de la declaración MiClase (y tenía una definición por separado en el archivo de origen ya que C++ no soporta const inicialización de tipos no integrales). Sin embargo, necesito acceder desde otros archivos y lógicamente parece que debería residir en el nivel del espacio de nombres.¿Qué efecto tiene static const tiene en un miembro de espacio de nombres

Mi pregunta es, ¿qué efecto tiene static const en este caso? Claramente, const significa que no puedo asignar un nuevo valor a GasConstant, pero qué significa un miembro estático en el espacio de nombre. ¿Esto es similar al estático en el alcance del archivo, donde no se puede acceder al miembro fuera de la unidad?

+0

¿Está esto en un archivo de encabezado (.h) o en un archivo de implementación (.cpp) ??? – AnT

+0

Está en un archivo de encabezado (.h). –

+2

En C++ no hay alcance de archivo. Solo hay ámbitos de espacios de nombres en C++ si está fuera de funciones y clases. Además, si lee en algunas páginas lo que ellos llaman "global", generalmente significan el espacio de nombres global y otros espacios de nombres incluidos. 'cplusplus.com' es conocido por su uso impreciso de la palabra" global ", por ejemplo. Entonces, si algo explica los efectos de "estática" en "alcance global", generalmente se refieren a su efecto en el alcance del espacio de nombres. –

Respuesta

7

El uso de static en el ámbito de espacio de nombres es fue * obsoleto en C++. Normalmente solo se vería en un archivo fuente, donde su efecto es hacer que la variable sea local para ese archivo fuente. Es decir, otro archivo fuente puede tener una variable exactamente del mismo nombre sin conflicto.

En C++, la forma recomendada de hacer variables locales al archivo de origen es usar un espacio de nombre anónimo.

Creo que es justo decir que el static en el encabezado de su código es simplemente incorrecto.

* Como señaló Tom en los comentarios (y en este answer), el comité C++ revirtió la decisión de desaprobar el uso de static en el alcance del archivo, sobre la base de que este uso siempre será parte del lenguaje (por ejemplo, Compatibilidad C).

+1

Forma recomendada de hacer esto ... ¿qué quiere decir exactamente con "esto"? No estoy seguro de que sea claro para mí. –

+1

La decisión de desaprobar la estática a nivel del espacio de nombres no es más: http://stackoverflow.com/questions/4726570/deprecation-of-the-static-keyword-no-more, lo que hace que esta respuesta sea incorrecta, ya que ahora usa espacios de nombres anónimos o estático son dos maneras aceptadas y correctas de lograr lo mismo. – Tom

+0

Gracias por la actualización, @Tom - Actualizaré la respuesta. –

4

MSDN dice:

Al modificar una variable, la palabra clave static especifica que la variable tiene una duración estática (se asigna cuando se inicia el programa y desasigna cuando termina el programa) y inicializa a 0 a menos que se especifique otro valor de . Cuando se modifica una variable o función en el ámbito de archivo, la palabra clave static especifica que la variable o función tiene enlace interno (su nombre no es visible desde el exterior el archivo en el que se declaró ).

Recuerde que incluir archivos de encabezado significa reemplazar la dirección "#include" con el código real del archivo de encabezado. Por lo tanto, las variables estáticas serán visibles solo en el archivo ".cpp" (que se compila) que incluye los dos archivos de encabezado.

De modo que cada archivo "cpp" que incluya los encabezados tendrá su propia variable estática.

+0

Ahora he declarado/definido GasConstant en un Constants.h que está incluido en MyClass.h. Parece que solo será visible en archivos que incluyan Constants.h o MyClass.h, y no de ningún otro archivo que no lo haga. ¿Qué pasa si otro archivo incluye ambos? –

+3

Cada archivo .cpp obtendrá su propia copia independiente. Puede que no sea lo que quieres ... o tal vez lo sea. Para los archivos .cpp que incluyen ambos, esto no debería cambiar nada pero, por supuesto, necesitará las protecciones de encabezado adecuadas. –

+0

Parece que lo que quiero hacer es simplemente const. –

1

Si se trata de un archivo de encabezado, entonces static no tiene ningún efecto en este caso. const objetos ya tienen enlace interno de forma predeterminada en C++, por lo que si lo declaras con static o sin static no hace diferencia alguna.

Supongo que simplemente movió la declaración de la clase al espacio de nombres. Pero static tiene un significado totalmente diferente en el contexto de la declaración de clase y en el contexto del espacio de nombres. Dentro de la clase, necesitabas static. En el espacio de nombres, el static es superfluo.

+0

pero ¿no es cierto que los archivos separados que incluían el encabezado tendrían instancias separadas del miembro del espacio de nombres como resultado de un funcionamiento estático similar al del archivo estático? Esto no importará por supuesto desde su creación, es decir, esto sería un problema si pensara que los dos archivos tenían acceso al mismo miembro y la actualización de uno se reflejaría en el otro. Solo trato de mantenerlo en línea. –

+1

De hecho, no necesita 'static' en la clase. Con él y sin él, ambos son inválidos para 'doble' :) –

Cuestiones relacionadas