2010-04-09 36 views

Respuesta

130

en cualquier parte de una unidad compilación (por lo general 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 las normas debe definir i fuera de la definición de clase (como es j) si se utiliza en el código que no sea simplemente expresiones constantes integrales . Vea el comentario de David a continuación para más detalles.

+21

He votado hacia arriba, pero después de revisar la norma hay un error en su código: 'i' debe estar * definido * en la cpp. §9.4.2/4 * Si un miembro de datos estático es de tipo const integral o const enumeration, su declaración en la definición de clase puede especificar un constante-inicializador que será una expresión de 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 alcance del espacio de nombres no contendrá un inicializador. * –

+3

Según su cita de los estándares, parece que 'i' tendría que ser definido * solo * si se usó 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 en términos estrictos, el ejemplo anterior es correcto si no hay otro código. Ahora aprecio tu comentario (+1), ¡todavía estoy aprendiendo cosas yo mismo! Así que intentaré aclarar ese punto en la respuesta, por favor avíseme si es mejor ... – squelart

+0

@squelart Disculpe si sueno tonto pero sería un ejemplo de enunciado diferente a la expresión constante integral? – Saksham

8

En una unidad de traducción en el mismo espacio de nombres, por lo general 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; 
} 
12

Los miembros estáticos necesitan ser inicializado en una unidad de traducción en el ámbito de archivo .cpp o en el espacio de nombre adecuado:

const string foo::s("my foo"); 
1

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.

-1
const string foo::s("my foo"); 

Y debe ser inicializado en el archivo de origen, de lo contrario va mal cuando se invoca en el caso de prueba.

Cuestiones relacionadas