gpt4 book ai didi

c++ - 确保全局记录器对象的生命周期比其他全局对象长

转载 作者:太空宇宙 更新时间:2023-11-04 11:52:45 26 4
gpt4 key购买 nike

我有一个包含一些单例对象的应用程序。他们想在构造和销毁时写入日志消息,这发生在全局变量的初始化时。现在,日志提供程序也是一个像这样的单例对象:

// 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 字段实际上是在一些记录器声明之后初始化的。现在我知道无法控制跨文件的全局变量的初始化,那么有没有其他方法可以让它工作?

最佳答案

只需使用经典的单例习语。你不想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,并在他们的析构函数中刷新它。)

关于c++ - 确保全局记录器对象的生命周期比其他全局对象长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17405209/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com