确保全局记录器对象的寿命比其他全局对象长



我有一个带有一些单例对象的应用程序。他们希望在构造和销毁时编写日志消息,这发生在全局变量初始化时。现在,日志记录提供程序也是一个单例对象,如下所示:

// 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,并将其放入销毁程序中。)

最新更新