En C++, las clases pueden tener miembros estáticos y no estáticos (variables y funciones). Se introdujeron para soportar datos comunes (para todos los objetos de la clase), así como funciones que no requieren acceso al estado de un instancia específica.
Es importante distinguir entre miembros estáticos y no estáticos, ya que tienen ciclos de vida, ámbitos de visibilidad y reglas de inicialización diferentes. Los errores frecuentes incluyen: definiciones incorrectas, uso simultáneo de miembros de instancia y estáticos, definiciones duplicadas en encabezados.
Las variables estáticas de clase se declaran dentro de la clase como static, pero deben ser definidas por separado fuera de la clase (hasta C++17). Existen en una única instancia. Las funciones estáticas no tienen acceso a miembros no estáticos (de instancia) sin una referencia explícita.
Ejemplo de código:
class Counter { public: static int count; Counter() { ++count; } static void Reset() { count = 0; } }; int Counter::count = 0;
Características clave:
¿Se puede inicializar una variable estática de clase directamente dentro de la clase (hasta C++17)?
No, hasta C++17 se debe proporcionar una definición fuera de la clase. En C++17 y versiones posteriores, para static inline es posible definir directamente dentro de la clase.
// C++17 class Foo { inline static int counter = 0; };
¿Tiene una función estática de clase acceso a this o a miembros no estáticos?
No, los miembros estáticos no tienen acceso a miembros no estáticos o a this, incluso si se crean instancias de la clase. Para referirse a ello, es necesario pasar explícitamente el objeto.
¿Se creará un miembro estático de clase en cada instancia de la clase?
No, los miembros estáticos existen en una única instancia para toda la clase independientemente del número de objetos.
El desarrollador declara static int en la clase, pero no lo define fuera de la clase. El enlazador da un error de símbolo indefinido, ya que el miembro estático no se inicializa.
Pros:
Contras:
El miembro estático se declara en la clase, se define fuera de la clase y se utiliza como un contador de objetos creados.
Pros:
Contras: