我正在尝试为 Ogre(一种开源 3D 引擎)的标准日志记录类制作一个包装器。我希望它具有与 std::cerr
相同的语法, 在 Linux 上运行时也会输出到 cerr。这是我拥有的:
#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
现在,这工作正常,并且这个单例在 .cpp 中实例化:
#include "logger.h"
Logger* Logger::m_Instance = new Logger();
当我想在多个 header 中使用单例时,问题就来了。我在 game3d.h
中实例化它,它包含在几乎所有标题中,如下所示:
Logger awesomelogger = Logger::getInstance();
不幸的是,这会产生多个有关 header 尝试重新声明 awesomelogger
的错误.
我想让它成为一个 const,这会使它消失,但会引入新的错误。这是我尝试过的:
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;
}
我的问题是:如何使此类常量的实例或如何重写此类但仍然能够做到 awesomelogger << "output" << s_Stuff << "\n";
最佳答案
与您的问题无关,但请注意 _LOGGER_H_
和 __LogManager_H__
等名称在 C++ 中是保留的 - 您不能在自己的代码中使用它们。如果您不理解有关名称开头的下划线(或任何地方的双下划线)的规则,请不要使用它们。
现在,关于您的问题,记录器显然不是常量。提供对单例的访问的经典方法是对此的一些变体:
static Logger* getInstance() {
static Logger logger;
return & logger;
}
关于c++ - 我怎样才能创建我的单例常量实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1150698/