我有一个带有一些单例对象的应用程序。他们希望在构造和销毁时编写日志消息,这发生在全局变量初始化时。现在,日志记录提供程序也是一个单例对象,如下所示:
// loggingProvider.h
class LoggingProvider {
static boost::shared_ptr<LoggingProvider> instance;
public:
static boost::shared_ptr<LoggingProvider> getInstance();
/* ... */
};
// loggingProvider.cpp
boost::shared_ptr<LoggingProvider> LoggingProvider::instance;
boost::shared_ptr<LoggingProvider> getInstance() {
if (!instance) {
instance.reset(new LoggingProvider());
}
return instance;
}
记录器界面如下所示:
// logger.h
class Logger {
const boost::shared_ptr<LoggingProvider> provider;
const std::string prefix;
public:
Logger(const std::string prefix);
/* ... */
}
// logger.cpp
Logger::Logger(const std::string& prefix) :
provider(LoggingProvider::getInstance()), prefix(prefix) {}
其思想是能够在多个cpp文件中将记录器声明为全局变量,并确保日志记录提供程序在所有记录器都被销毁后被销毁,因为它是由boost::shared_ptr
管理的。如果我在一个文件的顶部声明一个像这样的记录器,那么它肯定会在同一文件中的任何单个对象之后被销毁:
// somewhere.cpp
static Logger logger("Somewhere");
遗憾的是,此代码不起作用。当我调试它时,LoggingProvider
的实例被创建了多次。我相信这是因为instance
字段实际上是在一些记录器声明之后初始化的。现在我知道不可能控制跨文件全局变量的初始化,那么有其他方法可以实现吗?
只需使用经典的singleton习惯用法。你不想shared_ptr
,因为您不想破坏对象,永远。基本上,类似于:
class LoggingProvider
{
static LoggingProvider* our_instance;
public:
static LoggingProvider& instance();
// ...
};
LoggingProvider* LoggingProvider::our_instance
= &LoggingProvider::instance();
LoggingProvider&
LoggingProvider::instance()
{
if ( our_instance == NULL ) {
our_instance = new LoggingProvider;
}
return *our_instance;
}
这里重要的是1)指针没有琐碎的东西构造函数,并且2)该实例从未被破坏。
有一点:因为你输出到的任何文件都不会关闭时,请确保刷新所有输出。(我通常这样做使用实际记录器的短期临时实例,其从CCD_ 5获取目标流buf,并将其放入销毁程序中。)