Bonjour,
Tous le monde utilise des librairies personnelles ou non.
Certaines doivent être initialisées.
Généralement à l'aide d'une fonction comme Init() et Quit().
Dans des projets qui contiennent un certains nombres de fichiers, il m'arrive de m'y perdre et j'oublie ces fameux Init().
Mais des libraires fonctionnent quand même sans avoir lancer l'Init().
Je me dit, problème, si j'oublie un Init() sans m'en rendre compte il pourrait y avoir des erreurs très difficiles à détecter ou des fuites de mémoires.
Pour mes libraires, je me suis dit que cela serait bien qu'elle s'initialisent automatiquement de façon transparente pour l'utilisateur :
main.cpp
autoInit.hpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 #include <iostream> #include "autoInit.hpp" int main(int argc, char* argv[]){ std::cout << "Init:"<< NP::IsInit() << "\n"; return 0; }
autoInit.cpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 #ifndef AUTOINIT_HPP_INCLUDED #define AUTOINIT_HPP_INCLUDED namespace NP { bool IsInit(); } #endif // AUTOINIT_HPP_INCLUDED
Comme vous pouvez le voir, je place une class sans variable dans un namespace anonyme 'AutoInit' (ligne 14 à 24).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
27
28
29
30
31
32 #include <iostream> #include "autoInit.hpp" namespace { void gInit(){ std::cout << "Init()\n"; } void gQuit(){ std::cout << "Quit()\n"; } bool gIsInit = false; class AutoInit{ public: AutoInit(){ gInit(); gIsInit = true; } ~AutoInit(){ gQuit(); gIsInit = false; } }; AutoInit gAutoInit; } namespace NP { bool IsInit(){ return gInit; } }
Une instance de cette class est généré à la compilation du fichier, mais pas dynamiquement, donc pas besoin de 'delete' (ligne 26).
Le constructeur (ligne 16 à 19) fait appel a ma fonction 'Init()' qui se trouve elle même dans le namespace anonyme (ligne 5 à 7).
Tandis que le déstructeur (ligne 20 à 23) appel 'Quit()' (ligne 8 à 10).
ctor et dtor modifie également une variable situé dans le namespace anonyme pour connaitre l'état de l'initialisation (même si cela n'est plus nécessaire en fait, c'est juste pour le test) 'gIsInit' (ligne 12).
Quand je lance mon projet, il fonctionne bien comme je le souhaite.
La librairie s'initialise et se quitte toute seul.
Pour que vous compreniez mieux, voici quelques précisions :Init()
Init:1
Quit()
Process returned 0 (0x0) execution time : 0.042 s
Press any key to continue.
- Les fonctions et variables dans le namespace anonymes sont global donc je les fait commencer par un g... (mon code est plus clair)
- Le NP est un namespace facultatif, mais j'utilise souvent un namespace spécifique pour chaque librairie afin de mieux regrouper les fonctions.
- Si mes souvenir son bon, il me semble qu'un fichier *.cpp n'est compilé qu'une seul fois, donc une seul instance de la classe 'AutoInit'.
J'ai fais ce bout de code qui me semble être une bonne idée, mais je voudrais connaitre les avantages et inconvénients d'une tel méthode, qu'en pensez vous ?
ps. j'ai testé un singleton dans le namespace anonyme ... ne fonctionne pas... mais de toute façon cela reviendrait au même et sans avantage supplémentaires.
Partager