C ++ inicializa variables estáticas en clase?

Me he dado cuenta de que algunas de mis funciones en una clase en realidad no están accediendo al objeto, por lo que las convertí en static . Luego, el comstackdor me dijo que todas las variables a las que acceden también deben ser estáticas, bueno, bastante comprensibles hasta ahora. Tengo un montón de variables de cadena como

 string RE_ANY = "([^\\n]*)"; string RE_ANY_RELUCTANT = "([^\\n]*?)"; 

y así sucesivamente en la clase. Luego los hice todos static const porque nunca cambian. Sin embargo, mi progtwig solo se comstack si los saco de la clase: de lo contrario, MSVC ++ 2010 se queja de que “solo se pueden inicializar variables integrales constantes estáticas dentro de una clase”.

Bueno, eso es desafortunado. ¿Hay alguna solución? Me gustaría dejarlos dentro de la clase a la que pertenecen.

No se pueden inicializar dentro de la clase, pero se pueden inicializar fuera de la clase, en un archivo fuente:

 // inside the class class Thing { static string RE_ANY; static string RE_ANY_RELUCTANT; }; // in the source file string Thing::RE_ANY = "([^\\n]*)"; string Thing::RE_ANY_RELUCTANT = "([^\\n]*?)"; 

Actualizar

Acabo de notar la primera línea de su pregunta: no quiere que esas funciones sean static , quiere que sean const . Hacerlos static significa que ya no están asociados con un objeto (por lo que no pueden acceder a ningún miembro no estático), y hacer que los datos sean estáticos significa que se compartirán con todos los objetos de este tipo. Esto bien puede no ser lo que quieres. Haciéndolos const simplemente significa que no pueden modificar ningún miembro, pero aún pueden acceder a ellos.

Mike Seymour le ha dado la respuesta correcta, pero para agregar …
C ++ le permite declarar y definir en su cuerpo de clase solo los tipos integrales de const static , como dice el comstackdor. Entonces puedes hacer:

 class Foo { static const int someInt = 1; static const short someShort = 2; // etc. }; 

Y no puede hacer eso con ningún otro tipo, en esos casos debe definirlos en su archivo .cpp.

Las variables de miembros estáticos deben declararse en la clase y luego definirse fuera de ella.

No hay solución alternativa, solo ponga su definición real en un archivo fuente.


Según su descripción, huele como si no estuviera usando las variables estáticas de la manera correcta. Si nunca cambian, debe usar una variable constante, pero su descripción es demasiado genérica para decir algo más.

Las variables de miembro estático siempre tienen el mismo valor para cualquier instancia de tu clase: si cambias una variable estática de un objeto, también cambiará para todos los demás objetos (y de hecho también puedes acceder a ellos sin una instancia de la clase – es decir: un objeto).

Desde C ++ 11 se puede hacer dentro de una clase con constexpr .

 class stat { public: // init inside class static constexpr double inlineStaticVar = 22; }; 

Ahora se puede acceder a la variable con:

 stat::inlineStaticVar 

Siento que vale la pena agregar que una variable estática no es lo mismo que una variable constante.

usando una variable constante en una clase

 struct Foo{ const int a; Foo(int b) : a(b){} } 

y lo declararíamos como así

 fooA = new Foo(5); fooB = new Foo(10); // fooA.a = 5; // fooB.a = 10; 

Para una variable estática

 struct Bar{ static int a; Foo(int b){ a = b; } } Bar::a = 0; // set value for a 

que se usa como tal

 barA = new Bar(5); barB = new Bar(10); // barA.a = 10; // barB.a = 10; // Bar::a = 10; 

Ves lo que sucede aquí. La variable constante, que se instancia junto con cada instancia de Foo, como instancia de Foo tiene un valor separado para cada instancia de Foo, y Foo no puede cambiarla en absoluto.

Donde al igual que con Bar, su único valor para Bar :: a no importa cuántas instancias de Bar se realicen. Todos comparten este valor, también puedes acceder a él con sus instancias de Bar. La variable estática también cumple las reglas para público / privado, por lo que podría hacer que solo las instancias de Bar puedan leer el valor de Bar :: a;

Solo para agregar encima de las otras respuestas. Para inicializar un miembro estático complejo , puede hacerlo de la siguiente manera:

Declare su miembro estático como de costumbre.

 // myClass.h class myClass { static complexClass s_complex; //... }; 

Haga una pequeña función para inicializar su clase si no es trivial hacerlo. Esto se llamará solo la única vez que se inicializa el miembro estático. (Tenga en cuenta que se utilizará el constructor de copias de complexClass, por lo que debe estar bien definido).

 //class.cpp #include myClass.h complexClass initFunction() { complexClass c; c.add(...); c.compute(...); c.sort(...); // Etc. return c; } complexClass myClass::s_complex = initFunction(); 

Si su objective es inicializar la variable estática en su archivo de encabezado (en lugar de un archivo * .cpp, que puede desear si se atiene a una expresión de “solo encabezado”), puede solucionar el problema de inicialización utilizando un modelo. Las variables estáticas templadas se pueden inicializar en un encabezado, sin causar que se definan múltiples símbolos.

Vea aquí para un ejemplo:

Inicialización de miembro estático en una plantilla de clase

Opcionalmente, mueva todas sus constantes al archivo .cpp sin statement en el archivo .h. Use el espacio de nombres anónimo para hacerlos invisibles más allá del módulo cpp.

 // MyClass.cpp #include "MyClass.h" // anonymous namespace namespace { string RE_ANY = "([^\\n]*)"; string RE_ANY_RELUCTANT = "([^\\n]*?)"; } // member function (static or not) bool MyClass::foo() { // logic that uses constants return RE_ANY_RELUCTANT.size() > 0; } 

Algunas respuestas parecen ser engañosas un poco.

No tienes que

  • Asignar un valor al objeto estático al inicializar, asignar un valor es Opcional .
  • Cree otro archivo .cpp para inicializarlo. Se puede hacer de la misma manera en el archivo de encabezado .

 #ifndef CLASS_A_H #define CLASS_A_H #include  class A { private: static std::string str; static int x; }; // Initialize with no values std::string A::str; int A::x; // Initialize with values //std::string A::str = "SO!"; //int A::x = 900; #endif