Auto initialisation d'une librairie
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
Code:
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.hpp
Code:
1 2 3 4 5 6 7 8
| #ifndef AUTOINIT_HPP_INCLUDED
#define AUTOINIT_HPP_INCLUDED
namespace NP {
bool IsInit();
}
#endif // AUTOINIT_HPP_INCLUDED |
autoInit.cpp
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 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;
}
} |
Comme vous pouvez le voir, je place une class sans variable dans un namespace anonyme 'AutoInit' (ligne 14 à 24).
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.
Citation:
Init()
Init:1
Quit()
Process returned 0 (0x0) execution time : 0.042 s
Press any key to continue.
Pour que vous compreniez mieux, voici quelques précisions :
- 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.