web-dev-qa-db-fra.com

Symbole externe non résolu sur les membres statiques de la classe

Très simplement:

J'ai une classe composée principalement de membres publics statiques. Je peux donc regrouper des fonctions similaires qui doivent encore être appelées à partir d'autres classes/fonctions.

Quoi qu'il en soit, j'ai défini deux variables de caractère non signées statiques dans l'étendue publique de ma classe. Lorsque j'essaie de modifier ces valeurs dans le constructeur de la même classe, une erreur "Symbole externe non résolu" s'affiche lors de la compilation.

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

    ...

    test();
};

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

Je suis nouveau en C++, alors allez-y doucement. Pourquoi je ne peux pas faire ça?

121
Daniel

Vous avez oublié d'ajouter les définitions correspondant à vos déclarations de X et Y

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

quelque part. Vous voudrez peut-être aussi initialiser un membre statique

unsigned char test::X = 4;

et encore une fois, vous faites cela dans la définition (généralement dans un fichier CXX) et non dans la déclaration (qui est souvent dans un fichier .H)

134
Colin Jensen

Les déclarations de membres de données statiques dans la déclaration de classe ne sont pas leur définition. Pour les définir, vous devez le faire dans le .CPP fichier pour éviter les symboles en double.

Les seules données que vous pouvez déclarer et définir sont des constantes statiques intégrales. (Les valeurs de enums peuvent également être utilisées comme valeurs constantes)

Vous voudrez peut-être réécrire votre code comme suit:

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

test::test() {
}

Si vous voulez avoir la possibilité de modifier vos variables statiques (autrement dit, lorsqu'il est inapproprié de les déclarer en tant que const), vous pouvez séparer votre code entre .H et .CPP de la manière suivante:

.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.
}
60
sergtk

Comme il s’agit du premier fil SO qui semblait s’être présenté lors de la recherche de "noms externes non résolus avec des membres const statique" en général, je laisserai un autre indice pour résoudre un problème avec des noms externes non résolus. ici:

Pour moi, la chose que j'ai oubliée est de marquer ma définition de classe __declspec(dllexport), et lorsqu'elle est appelée depuis une autre classe (en dehors des limites de la dll de cette classe), j'ai bien sûr l'erreur externe non résolue.
Néanmoins, il est facile d’oublier lorsque vous modifiez une classe d’aides internes en une classe accessible d’ailleurs. Par conséquent, si vous travaillez dans un projet lié de manière dynamique, vous pouvez également le vérifier.

3

dans mon cas, j'ai déclaré une variable statique dans le fichier .h, comme

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

et dans myClass.cpp, j'ai essayé d'utiliser ce m_nMyVar. Il y a eu une erreur de lien comme:

erreur LNK2001: symbole externe non résolu "public: classe statique ... Le fichier cpp lié à une erreur de lien se présente comme suit:

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

J'ajoute donc le code ci-dessous en haut 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
}

alors LNK2001 est parti.

2
Penny