Respuestas:
Cualquier lugar en una unidad de compilación (generalmente un archivo .cpp) haría:
foo.h
class foo {
static const string s; // Can never be initialized here.
static const char* cs; // Same with C strings.
static const int i = 3; // Integral types can be initialized here (*)...
static const int j; // ... OR in cpp.
};
foo.cpp
#include "foo.h"
const string foo::s = "foo string";
const char* foo::cs = "foo C string";
// No definition for i. (*)
const int foo::j = 4;
(*) De acuerdo con los estándares, debe definir i
fuera de la definición de clase (como j
es) si se usa en un código que no sea solo expresiones constantes integrales. Vea el comentario de David a continuación para más detalles.
i
que tendría que definirse solo si se usara en otro lugar que no sea en expresiones constantes integrales, ¿verdad? En este caso, no puede decir que hay un error porque no hay suficiente contexto para estar seguro, o hablando estrictamente, el ejemplo anterior es correcto si no hay otro código. Ahora aprecio tu comentario (+1), ¡todavía estoy aprendiendo cosas! Así que intentaré aclarar ese punto en la respuesta, por favor avíseme si es mejor ...
int f() { return 42; } class foo { static const int i = f(); /* Error! */ }
cuenta que C ++ 11 permite llamar a las funciones 'constexpr':constexpr int f() { return 42; } class foo { static const int i = f(); /* Ok */ }
Los miembros estáticos deben inicializarse en una unidad de traducción .cpp en el ámbito del archivo o en el espacio de nombres apropiado:
const string foo::s( "my foo");
En una unidad de traducción dentro del mismo espacio de nombres, generalmente en la parte superior:
// foo.h
struct foo
{
static const std::string s;
};
// foo.cpp
const std::string foo::s = "thingadongdong"; // this is where it lives
// bar.h
namespace baz
{
struct bar
{
static const float f;
};
}
// bar.cpp
namespace baz
{
const float bar::f = 3.1415926535;
}
Solo los valores integrales (por ejemplo, static const int ARRAYSIZE
) se inicializan en el archivo de encabezado porque generalmente se usan en el encabezado de clase para definir algo como el tamaño de una matriz. Los valores no integrales se inicializan en el archivo de implementación.
i
debe definirse en el cpp. §9.4.2 / 4 Si un miembro de datos estáticos es de tipo const integral o de enumeración const, su declaración en la definición de clase puede especificar un inicializador constante que será una expresión constante integral (5.19). En ese caso, el miembro puede aparecer en expresiones constantes integrales. El miembro aún se definirá en un ámbito de espacio de nombres si se usa en el programa y la definición del ámbito de espacio de nombres no contendrá un inicializador.