我有一些带有一些单例对象的应用程序。他们希望在构造和销毁时编写日志消息,这在全局变量的初始化时发生。现在,日志记录提供程序也是一个单例对象,如下所示:
// 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文件中的全局变量,并确保在所有记录器被销毁后销毁日志记录提供程序,因为它由{{1}管理}。如果我在文件的顶部声明这样的记录器,则保证在同一文件中的任何单个对象之后被破坏:
boost::shared_ptr
可悲的是,这段代码不起作用。当我调试它时,// somewhere.cpp
static Logger logger("Somewhere");
的实例被多次创建。我相信情况就是这样,因为LoggingProvider
字段实际上是在一些记录器声明之后初始化的。现在我知道没有办法控制跨文件的全局变量的初始化,那么还有另一种方法可以让它工作吗?
答案 0 :(得分:1)
只需使用经典的单身成语。你不想要
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)实例永远不会被破坏。
有一件事:因为你输出的任何文件永远不会
关闭,确保刷新所有输出。 (我通常这样做
使用实际记录器的短期临时实例,
从LoggerProvider
获取目标streambuf,
并在它们的析构函数中刷新它。)