bonjour,
Comme l'explique le titre je voudrais initialiser un static map:
Je voudrais qu'il soit vide au départ.Code:static std::map<T1,T2> conteneur_map;
J'ai trouvé des doc et autres dessus mais je n'ai rien compris...
Merci d'avance
Version imprimable
bonjour,
Comme l'explique le titre je voudrais initialiser un static map:
Je voudrais qu'il soit vide au départ.Code:static std::map<T1,T2> conteneur_map;
J'ai trouvé des doc et autres dessus mais je n'ai rien compris...
Merci d'avance
Si la map est un membre statique d'une classe - elle sera vide par défaut - mais il me semble que la solution la plus 'sûre' serait de créer un couple de fonctions qui initialise et de-initialise la partie statique de la classe.
Il faudrait donc appeler la fonction sInit avant d'instancer la classe et appeler sClose en fin de programme ou lorsque la classe n'est plus utile.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 class A { static bool ms_bInitialised = false; static std::map<T1,T2> conteneur_map; static void sInit(); static void sClose(); } static void A::sInit() { if(!ms_bInitialised)// à remplacer par un assert si nécessaire { conteneur_map = std::map<T1,T2>(); ms_bInitiliased = true; } } static void A::sClose() { if(ms_bInitialised)// à remplacer par un assert si nécessaire { conteneur_map.clear(); ms_bInitiliased = false; } ; }
désolé pour la précision mais c'est bien static de classe, donc à initialiser à l'extérieur sinon erreur de linker (c'est mon cas). Il faudrait donc faire quelque chose comme:
Enfin je crois. Je pense qu'il faudrait créer un map du même type et faire égal (mais j'ai tester et ça ne veut pas non plus).Code:std::map<T1,T2> ClasseProprietaire::conteneur_map = "quelque chose";//en dehors de la classe
Non, il suffit de la définir à l'extérieur de la classe (une seule fois dans le programme) :
ou bienCode:
1
2
3 // dans ClasseProprietaire.cpp : std::map<T1,T2> ClasseProprietaire::conteneur_map; // initialisation par défaut (vide)
ouCode:
1
2std::map<T1,T2> ClasseProprietaire::conteneur_map = une_autre_map; // initialisation par recopie
Code:
1
2 std::map<T1,T2> ClasseProprietaire::conteneur_map (debut, fin); // initialisation avec la range [debut, fin)
trop simple pour y penser^^. Je ne sais pas pourquoi mais en mettant la définition juste après la classe, le compilo considérait ça comme une déclaration. En fait il suffisait de le déplacer dans le .cpp mais je ne sais pas pourquoi. En attendant : :resolu:
Bien sûr, par définition toute définition est aussi une déclaration.
Blague à part (je vois ce que tu veux dire!), je crois que tu te trompes.
Le compilateur proprement dit[1] ne fait pas la différence : il ne voit qu'une série de déclarations, il n'a aucun idée si tu les as mises dans un en-tête ou dans un .cpp.
La différence, c'est si tu inclus un en-tête à plusieurs endroits, son contenu se trouve dupliqué.
Le préprocesseur est juste ça : un outil pour dupliquer des déclarations de façon adéquate.
[1] techniquement : phase 7 de la traduction,
Parce que je n'aime faire le nettoyage de manière implicite par le destructeur. J'aime bien le faire de manière explicite. Peut être une habitude que j'ai prise du C.
Bon, c'est sur que dans ce cas, il y a la méthode map.clear() qui fait la même chose (et qui est certainement appelée par le destructeur)
Je ne suis pas sûr que je vais être clair, mais sInit/sClose permet aussi d'encapsuler la logique de la classe de manière plus visible. Par exemple, si tu avais une map de pointeurs plutôt qu'une map d'objets,seuls l'implémentation de sInit et de sClose permettrait de traiter les deux cas suivant :
- ta classe est propriétaire du contenu de la map et doit désallouer le contenu avant de sortir
- ta classe n'est pas propriétaire du contenu de la map et elle ne fait que vider la map.
Ce sont des garde-fous pas forcément nécessaires mais qui rendent le code plus maintenable à mon avis.