la clase puede ser declarado en la cabecera, sino que debe ser definido en un archivo .cpp. Esto se debe a que solo puede haber una instancia de una variable estática y el compilador no puede decidir en qué archivo de objeto generado se va a ubicar, por lo que debe tomar la decisión.
Para mantener la definición de un valor estático con la declaración en C++ 11 se puede utilizar una estructura estática anidada. En este caso, el miembro estático es una estructura y debe definirse en un archivo .cpp, pero los valores están en el encabezado.
class A
{
private:
static struct _Shapes {
const std::string RECTANGLE {"rectangle"};
const std::string CIRCLE {"circle"};
} shape;
};
En lugar de inicializar los miembros individuales de toda la estructura estática se inicializa en .cpp:
A::_Shapes A::shape;
Los valores se accede con
A::shape.RECTANGLE;
o - ya que los miembros son privados y están destinados a ser utilizados solo desde A - con
shape.RECTANGLE;
Tenga en cuenta que esta solución aún adolece del problema del orden de inicialización de las variables estáticas . Cuando se utiliza un valor estático en inicialice otra variable estática, la primera puede no inicializarse, todavía.
// file.h
class File {
public:
static struct _Extensions {
const std::string h{ ".h" };
const std::string hpp{ ".hpp" };
const std::string c{ ".c" };
const std::string cpp{ ".cpp" };
} extension;
};
// file.cpp
File::_Extensions File::extension;
// module.cpp
static std::set<std::string> headers{ File::extension.h, File::extension.hpp };
En este caso las variables estáticas cabeceras contendrán ya sea { ""} o { ".h", ".hpp"}, dependiendo del orden de inicialización creado por el enlazador.
Según lo mencionado por @ abyss.7 también puede usar constexpr
si el valor de la variable se puede calcular en tiempo de compilación. Pero si declara sus cuerdas con static constexpr const char*
y el programa utiliza std::string
de lo contrario habrá una sobrecarga porque se creará un nuevo std::string
objeto cada vez que se utiliza una constante tal:
class A {
public:
static constexpr const char* STRING = "some value";
};
void foo(const std::string& bar);
int main() {
foo(A::STRING); // a new std::string is constructed and destroyed.
}
¡Gracias por todas sus excelentes respuestas! ¡Viva SO! –
¿Puede alguien decirme qué tipo 'integral' es? Muchas gracias. –
Los tipos integrales se refieren a los tipos que representan números enteros. Consulte http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fintvar.htm – bleater