Cómo inicializar miembros de datos estáticos privados en un archivo de encabezado

Resuelto Jason Baker asked hace 15 años • 18 respuestas

¿Cuál es la mejor manera de inicializar un miembro de datos estáticos y privados en C++? Intenté esto en mi archivo de encabezado, pero me da errores extraños en el vinculador:

class foo
{
    private:
        static int i;
};

int foo::i = 0;

Supongo que esto se debe a que no puedo inicializar un miembro privado fuera de la clase. Entonces, ¿cuál es la mejor manera de hacer esto?

Jason Baker avatar Oct 09 '08 10:10 Jason Baker
Aceptado

La declaración de clase debe estar en el archivo de encabezado o en el archivo fuente, si la clase no se usa en otros archivos.

// foo.h
class foo
{
    private:
        static int i;
};

Sin embargo, la inicialización debe estar en el archivo fuente.

// foo.cpp
int foo::i = 0;

Si la inicialización se realiza en el archivo de encabezado, cada archivo que incluya el archivo de encabezado tendrá una definición del miembro estático. Por lo tanto, durante la fase de enlace, obtendrá errores del enlazador ya que el código para inicializar la variable se definirá en varios archivos fuente. La inicialización del static int idebe realizarse fuera de cualquier función.

Nota: Matt Curtis: señala que C++ permite la simplificación de lo anterior si el miembro de datos estáticos es de tipo entero constante ( bool, char, char8_t[desde C++ 20], char16_t, char32_t, wchar_t, short, int, long, long longo cualquier entero extendido definido por la implementación tipos, incluidas las variantes firmadas, no firmadas y calificadas por CV ). Luego puedes declarar e inicializar el miembro de datos directamente dentro de la declaración de clase en el archivo de encabezado:

class foo
{
    private:
        static int const i = 42;
};
Martin York avatar Oct 09 '2008 03:10 Martin York

Para una variable :

foo.h:

class foo
{
private:
    static int i;
};

foo.cpp:

int foo::i = 0;

Esto se debe a que sólo puede haber una instancia de foo::ien su programa. Es una especie de equivalente a extern int iun archivo de encabezado y int iun archivo fuente.

Para una constante puedes poner el valor directamente en la declaración de clase:

class foo
{
private:
    static int i;
    const static int a = 42;
};
Matt Curtis avatar Oct 09 '2008 03:10 Matt Curtis