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:
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;
};
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
///Logger.cpp
#include "CLogger.h"
 
CLogger* CLogger::m_pInstance = NULL;
Bon, mon code fonctionne, mais j'ai 2 problèmes:
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:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
CLogger* CLogger::m_pInstance = NULL;
En gros, il me dit: "This non-local object will be initialised at runtime."
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:
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)
Ce qui me permet de l'utiliser ainsi:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
INIT_LOG("c:/temp/log.txt");
LOG( "test " << 1234 << UnObjet << std::endl );