Bonjour tout le monde,
je viens d'implémenter un petit logger super simple (et trés spécifique à mon appli, c'est pourquoi je ne peux pas utiliser des logger existants). Etant donné que je ne dois en avoir qu'un dans toute mon appli, j'ai estimé qu'il était légitime d'en faire un singleton.
Voici, en gros, à quoi ressemble mon logger:
Je déclare et j'initialise le singleton dans Logger.cpp
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
33
34
35
36 /// Logger.h // includes et autres class Logger : public std::ofstream { public: static void Init(std::string filename) { if ( m_pInstance == NULL ) { m_pInstance = new Logger(filename); // ici, du code relatif à l'initialisation du logger } } static Logger& GetInstance() { if ( m_pInstance == NULL ) { m_pInstance = new Logger(); } return *m_pInstance; } // destructor (bon, en réalité, le destructeur est privé) ~CLogger(){close();} private: // constructor Logger(std::string filename = "c:/temp/log.txt") : std::ofstream( filename.c_str(), std::ios::app ) {} // unique Logger instance static CLogger* m_pInstance; };
Bon, mon code fonctionne, mais j'ai 2 problèmes:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 ///Logger.cpp #include "CLogger.h" CLogger* CLogger::m_pInstance = NULL;
1/ J'aimerais forcer l'utilisateur de cette classe à initialiser le logger. En gros, j'aurais aimé faire en sorte que si Logger::Init(monfichier); n'est pas appelé, ça génère une erreur à la compilation.
Mais je ne vois vraiment pas comment faire. Est-ce seulement possible?
2/ J'utilise un outil d'analyse de code qui me hurle dessus à la ligne:
En gros, il me dit: "This non-local object will be initialised at runtime."
Code : Sélectionner tout - Visualiser dans une fenêtre à part CLogger* CLogger::m_pInstance = NULL;
Et il me dit d'aller voir l'item #47 du livre "Effective C++, 2nd edition" de Scott Meyers.
Ce que j'ai fais. Et je ne suis pas plus avancé, car j'ai l'impression que mon implémentation est fidèle aux conseils du livre.
Voyez-vous où est mon erreur?
note: afin de simplifier l'utilisation de ce logger, j'ai défini les macros suivantes:
Ce qui me permet de l'utiliser ainsi:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 #define LOG(X) CLogger::GetInstance() << X << std::endl #define INIT_LOG(X) CLogger::Init(X)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 INIT_LOG("c:/temp/log.txt"); LOG( "test " << 1234 << UnObjet << std::endl );
Partager