Símbolo externo no resuelto en miembros de clase estática

Resuelto asked hace 16 años • 6 respuestas

En pocas palabras:

Tengo una clase que consta principalmente de miembros públicos estáticos, por lo que puedo agrupar funciones similares que aún deben llamarse desde otras clases/funciones.

De todos modos, he definido dos variables de caracteres estáticas sin firmar en el ámbito público de mi clase. Cuando intento modificar estos valores en el constructor de la misma clase, aparece un error de "símbolo externo no resuelto" durante la compilación.

class test 
{
public:
    static unsigned char X;
    static unsigned char Y;

    ...

    test();
};

test::test() 
{
    X = 1;
    Y = 2;
}

Soy nuevo en C++, así que ten cuidado conmigo. ¿Por qué no puedo hacer esto?

 avatar Oct 12 '08 14:10
Aceptado

Si está utilizando C++ 17, puede usar el inlineespecificador (consulte https://stackoverflow.com/a/11711082/55721 )


Si utiliza versiones anteriores del estándar C++, debe agregar las definiciones que coincidan con sus declaraciones de X e Y.

unsigned char test::X;
unsigned char test::Y;

en algún lugar. Es posible que también desee inicializar un miembro estático

unsigned char test::X = 4;

y nuevamente, lo hace en la definición (generalmente en un archivo CXX), no en la declaración (que a menudo está en un archivo .H).

Colin Jensen avatar Oct 12 '2008 07:10 Colin Jensen

Las declaraciones de miembros de datos estáticos en la declaración de clase no son una definición de ellos. Para definirlos debes hacer esto en el .CPParchivo para evitar símbolos duplicados.

Los únicos datos que puede declarar y definir son las constantes estáticas integrales. (Los valores de enumstambién se pueden utilizar como valores constantes)

Es posible que desee reescribir su código como:

class test {
public:
  const static unsigned char X = 1;
  const static unsigned char Y = 2;
  ...
  test();
};

test::test() {
}

Si desea tener la capacidad de modificar sus variables estáticas (en otras palabras, cuando no es apropiado declararlas como constantes), puede separar su código entre .Hy .CPPde la siguiente manera:

.H:

class test {
public:

  static unsigned char X;
  static unsigned char Y;

  ...

  test();
};

.CPP :

unsigned char test::X = 1;
unsigned char test::Y = 2;

test::test()
{
  // constructor is empty.
  // We don't initialize static data member here, 
  // because static data initialization will happen on every constructor call.
}
sergtk avatar Oct 12 '2008 08:10 sergtk

en mi caso, declaré una variable estática en el archivo .h, como

//myClass.h
class myClass
{
    static int m_nMyVar;
    static void myFunc();
}

y en myClass.cpp, intenté usar este m_nMyVar. Obtuvo un error de ENLACE como:

error LNK2001: símbolo externo no resuelto "público: clase estática... El archivo cpp relacionado con el error de enlace tiene este aspecto:

//myClass.cpp
void myClass::myFunc()
{
    myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}

Entonces agrego el siguiente código en la parte superior de myClass.cpp

//myClass.cpp
int myClass::m_nMyVar; //it seems redefine m_nMyVar, but it works well
void myClass::myFunc()
{
    myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}

entonces LNK2001 desapareció.

Penny avatar Sep 18 '2018 23:09 Penny

Dado que este es el primer hilo SO que me pareció surgir al buscar "externos no resueltos con miembros constantes estáticos" en general, dejaré otra pista para resolver un problema con elementos externos no resueltos aquí:

Para mí, lo que olvidé fue marcar la definición de mi clase __declspec(dllexport), y cuando me llamaron desde otra clase (fuera de los límites de la dll de esa clase), por supuesto obtuve el error externo no resuelto.
Aún así, es fácil de olvidar cuando cambias una clase auxiliar interna a una accesible desde otro lugar, por lo que si estás trabajando en un proyecto vinculado dinámicamente, también puedes verificarlo.

Johann Studanski avatar May 04 '2018 07:05 Johann Studanski