J'essaie de faire un wrapper pour la classe de journalisation standard d'Ogre (un moteur 3D open source). Je veux qu'il ait la même syntaxe que std::cerr
, et qu'il soit également envoyé à cerr sous Linux. Voici ce que j'ai:Comment puis-je créer une instance de mon singleton const?
#ifndef _LOGGER_H_
#define _LOGGER_H_
#ifndef _XSTRING_
#include <xstring>
#endif
#ifndef __LogManager_H__
#include "OgreLogManager.h"
#endif
class Logger
{
public:
static Logger* m_Instance;
static Logger* getInstance() { return m_Instance; }
static const Logger& getInstanceConst() { return *m_Instance; }
Logger& operator << (const std::string& a_Message)
{
m_Log.append(a_Message);
_CheckNewLine();
return *m_Instance;
}
Logger& operator << (const char* a_Message)
{
m_Log += a_Message;
_CheckNewLine();
return *m_Instance;
}
private:
std::string m_Log;
Logger()
{
m_Log = "";
}
void _CheckNewLine()
{
if (m_Log.at(m_Log.size() - 1) == '\n')
{
Ogre::LogManager::getSingleton().logMessage(m_Log);
#if OGRE_PLATFORM != PLATFORM_WIN32 && OGRE_PLATFORM != OGRE_PLATFORM_WIN32
std::cerr << m_Log;
#endif
m_Log.clear();
}
}
};
#endif
Maintenant, cela fonctionne très bien, et ce singleton est instancié dans un Cpp:
#include "logger.h"
Logger* Logger::m_Instance = new Logger();
Le problème vient quand je veux utiliser le singleton dans plusieurs têtes. J'instancier dans game3d.h
, qui est inclus par à peu près tous les en-têtes comme ceci:
Logger awesomelogger = Logger::getInstance();
Malheureusement, cela donne plusieurs erreurs sur les en-têtes essayant de redéclarer awesomelogger
. Je veux en faire un const, ce qui ferait disparaître cela, mais qui introduit de nouvelles erreurs. Voilà ce que j'ai essayé:
friend Logger& operator << (const Logger& a_Logger, const std::string& a_Message)
{
a_Logger.m_Log.append(a_Message);
a_Logger._CheckNewLine();
return *m_Instance;
}
Ma question est: comment puis-je faire une instance de cette classe constante ou comment puis-je réécrire cette classe, mais toujours capable de faire awesomelogger << "output" << s_Stuff << "\n";
Une discussion technique sur la façon de mettre en œuvre un singleton, avec fil de sécurité en C++ se trouve dans cet article: http://www.aristeia.com/Papers/DDJ%5FJul%5FAug%5F2004%5Frevised .pdf –