2011-07-26 5 views
0

j'ai une classe statique complète, en utilisant un std :: carteproblème en utilisant la variable statique dans une fonction statique

c'est le cas simplifié

.h

#ifndef KEYBOARD_H 
#define KEYBOARD_H 

#include <map> 

class Keyboad { 

    static std::map<char, bool> pressed;  

    static void keyPressedEvent(char _key); 

}; 

#endif 

Cpp

#include "Keyboard.h" 

void Keyboard :: keyPressedEvent(char _key) { 

    Keyboard :: pressed[_key] = true; 

} 

, mais il y a un problème avec la variable membre statique, parce que je reçois

Undefined symbols: 
"Keyboard::pressed", referenced from: 
__ZN15Keyboard7pressedE$non_lazy_ptr in Keyboard.o 
(maybe you meant: __ZN15Keyboard7pressedE$non_lazy_ptr) 
ld: symbol(s) not found 
collect2: ld returned 1 exit status 

quand je l'enlève, il fonctionne ok

pourquoi puis-je obtenir ce problème, il devrait y avoir aucun problème lors de l'utilisation statique variables:/

grâce

Répondre

7

Vous devez définir la carte pressed dans votre fichier .cpp:

#include "Keyboard.h" 
std::map<char, bool> Keyboard::pressed; 

// The rest as before 
+0

mais pourquoi, quand c'est déjà déclaré dans la classe Keyboad que j'inclus? –

+1

@Peter, il est déclaré dans votre classe, mais pas * défini *. –

+0

@Peter: Pensez au fichier d'en-tête comme une * description * de ce que votre classe "inclut" (ceci s'appelle * declaration *). Il suffit de vous laisser compiler le code, mais pour le lier dans un exécutable, vous devez également "produire les biens réels". C'est ce que fait la ligne supplémentaire ci-dessus (ceci s'appelle * définition *). – Jon

6

Vous devez ajouter ce fichier à .cpp

std::map<char, bool> Keyboad::pressed; 

Tenir compte des membres statiques de classe comme des variables globales. Le compilateur doit allouer de la mémoire pour eux à l'intérieur du seul fichier objet. Vous devez donc les définir dans le fichier source correspondant. Un membre statique dans la définition de classe est juste une déclaration.

2

Vous devez toujours fournir la définition, exactement comme vous l'avez fait pour la fonction . Ajoutez simplement

std::map<char, bool> Keyboard::pressed; 

dans un fichier source quelque part. (Pour la cartographie char s, vous pourriez aussi envisager simple

bool Keyboard::pressed[256]; 

, indexé avec le char converti en unsigned char.)

1

Prenons un cas simple. Une variable globale counter est déclarée dans plusieurs fichiers d'en-tête:

int counter; // This appears in 3 HEADER files. 

fichiers source peu le font renvoyer. Lorsque vous le compilez et le liez, le compilateur émet une erreur de l'éditeur de liens indiquant que counter est déjà défini dans certains fichiers .OBJ (le message d'erreur dépend du compilateur).

Pour résoudre ce problème, vous venez de mettre extern devant variable (en tous les fichiers d'en-tête):

extern int counter; // This appears in 3 HEADER files. 

Et quand vous reconstruisez il, l'éditeur de liens se plaindre que counter est définie nulle part.

Pour résoudre ce problème, vous définissez cette variable dans un fichier source (tout un):

int counter; 

Et il résout le problème.

La variable statique de classe n'est rien d'autre qu'une variable globale, accessible au format classname::variablename. L'accessibilité est la même - globale.

Questions connexes