【发布时间】:2020-08-05 09:23:25
【问题描述】:
我在使用 boost::locale::date_time 库编写包装类时遇到问题。具体来说,我无法从我的班级创建一个全局对象,尽管除此之外一切正常。
以下是相关示例代码:
// DateTimeWrapper.h
#include <boost\\locale\\date_time.hpp>
#include <boost\\locale.hpp>
class DateTimeWrapper
{
public:
DateTimeWrapper();
~DateTimeWrapper();
// ... Other methods...
protected:
boost::locale::date_time* m_date_time;
static void Init_Global_Locale();
static bool m_Global_Locale_Initialized;
};
// DateTimeWrapper.cpp
bool DateTimeWrapper::m_Global_Locale_Initialized = false;
DateTimeWrapper::DateTimeWrapper()
{
Init_Global_Locale();
// The following line will work for the local object,
// but throws a std::bad_cast exception for the global object
m_date_time = new boost::locale::date_time;
}
DateTimeWrapper::~DateTimeWrapper()
{
delete m_date_time;
}
void DateTimeWrapper::Init_Global_Locale()
{
if (!m_Global_Locale_Initialized)
{
boost::locale::generator gen;
std::locale l = gen("");
std::locale::global(l);
m_Global_Locale_Initialized = true;
}
}
// This object throws a std::bad_cast exception. Code runs normally if I comment out the following line.
DateTimeWrapper global_date_time_object;
int main()
{
// This object works just fine
DateTimeWrapper local_date_time_object;
// Do stuff with local_date_time_object...
return(0);
}
正如您在代码中看到的,我使用静态成员来确保在第一次创建 DateTimeWrapper 对象时初始化全局语言环境。通常,这可以防止在我创建 boost::locale::date_time 成员时引发 std::bad_cast 异常。但是,当创建的第一个 DateTimeWrapper 对象是全局实例时,我仍然会从该行收到异常。
请注意,通过调试器,我可以确认 Init_Global_Locale() 方法中的所有行都在构建全局对象期间运行。该示例代码还在同一个源文件中声明了 global_date_time_object 之前的 DateTimeWrapper::m_Global_Locale_Initialized,所以我知道这里的初始化顺序不是问题(通过调试器逐步确认)。
那么为什么代码适用于本地对象而不适用于全局对象,即使我可以看到所有代码行都以正确的顺序运行,对于两个版本?
【问题讨论】:
-
#include <boost\\locale\\date_time.hpp>应该是#include <boost/locale/date_time.hpp>,另一个也是如此 -
offtopic:在 include 中始终使用 unix 样式的目录分隔符
/。 VS 在没有警告的情况下正确处理。 -
上面的代码在我的机器上工作(在修复了斜杠之后)。我确实必须在我的编译行上添加
-lboost_system-mt -lboost_locale-mt(我编译为-std=c++17,使用Boost 1.72)。 -
@MarekR 我有一个只包含静态方法的助手类。其中一种方法使用静态的、固定的历史日期——我将其声明为助手类的静态成员。如果不是作为静态(即全局)成员变量,那么定义和使用此日期的更好方法是什么?我看到的唯一选择是每次调用静态方法时都在静态方法中创建本地版本的日期,这不仅效率低,而且比我想要的更不透明(该日期将被埋在函数内部而不是在文件的顶部,很容易看到或调整)。
标签: c++ boost global boost-date-time boost-locale